From 9f5423a440eeb9a326d729ffd225f4e6fc02c031 Mon Sep 17 00:00:00 2001 From: Arjun Shankar Date: Mon, 11 Nov 2024 18:26:37 +0100 Subject: [PATCH] Add error and FUSE based tests for fchmod (RHEL-50548) Resolves: RHEL-50548 --- glibc-RHEL-50548-1.patch | 94 ++++++++++++++++++++++++ glibc-RHEL-50548-2.patch | 44 ++++++++++++ glibc-RHEL-50548-3.patch | 149 +++++++++++++++++++++++++++++++++++++++ glibc.spec | 8 ++- 4 files changed, 294 insertions(+), 1 deletion(-) create mode 100644 glibc-RHEL-50548-1.patch create mode 100644 glibc-RHEL-50548-2.patch create mode 100644 glibc-RHEL-50548-3.patch diff --git a/glibc-RHEL-50548-1.patch b/glibc-RHEL-50548-1.patch new file mode 100644 index 0000000..15099a5 --- /dev/null +++ b/glibc-RHEL-50548-1.patch @@ -0,0 +1,94 @@ +commit 424d97be50488beb6196c0ff0bc3dfeb87b4281c +Author: Florian Weimer +Date: Fri Aug 30 20:37:18 2024 +0200 + + io: Add error tests for fchmod + + On Linux most descriptors that do not correspond to file system + entities (such as anonymous pipes and sockets) have file permissions + that can be changed. While it is possible to create a custom file + system that returns (say) EINVAL for an fchmod attempt, testing this + does not appear to be useful. + + Reviewed-by: Carlos O'Donell + +Conflicts: + io/Makefile + (usual tests conflict) + +diff --git a/io/Makefile b/io/Makefile +index 5284a1282dd07e3d..30dd48b8acf9dcb9 100644 +--- a/io/Makefile ++++ b/io/Makefile +@@ -79,7 +79,8 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ + tst-futimens \ + tst-utimensat \ + tst-closefrom \ +- tst-ftw-bz28126 ++ tst-ftw-bz28126 \ ++ tst-fchmod-errors + + tests-time64 := \ + tst-fcntl-time64 \ +diff --git a/io/tst-fchmod-errors.c b/io/tst-fchmod-errors.c +new file mode 100644 +index 0000000000000000..ee15300fc3edf6f0 +--- /dev/null ++++ b/io/tst-fchmod-errors.c +@@ -0,0 +1,56 @@ ++/* Test various fchmod error cases. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ { ++ /* Permissions on /dev/null (the opened descriptor) cannot be changed. */ ++ int fd = xopen ("/dev/null", O_RDWR, 0); ++ errno = 0; ++ TEST_COMPARE (fchmod (fd, 0), -1); ++ TEST_COMPARE (errno, EPERM); ++ xclose (fd); ++ ++ /* Now testing an invalid file descriptor. */ ++ errno = 0; ++ TEST_COMPARE (fchmod (fd, 0600), -1); ++ TEST_COMPARE (errno, EBADF); ++ } ++ ++ errno = 0; ++ TEST_COMPARE (fchmod (-1, 0600), -1); ++ TEST_COMPARE (errno, EBADF); ++ ++ errno = 0; ++ TEST_COMPARE (fchmod (AT_FDCWD, 0600), -1); ++ TEST_COMPARE (errno, EBADF); ++ ++ /* Linux supports fchmod on pretty much all file descriptors, so ++ there is no check for failure on specific types of descriptors ++ here. */ ++ ++ return 0; ++} ++ ++#include diff --git a/glibc-RHEL-50548-2.patch b/glibc-RHEL-50548-2.patch new file mode 100644 index 0000000..3236001 --- /dev/null +++ b/glibc-RHEL-50548-2.patch @@ -0,0 +1,44 @@ +commit 3844cdc33093dbe1e33ddb831eada9bdb4a482b9 +Author: Florian Weimer +Date: Fri Aug 30 22:07:12 2024 +0200 + + io: Fix destructive nature of tst-fchmod-errors + + We must not change the permissions of /dev/null if running + as root. + + Reviewed-by: Carlos O'Donell + +diff --git a/io/tst-fchmod-errors.c b/io/tst-fchmod-errors.c +index ee15300fc3edf6f0..bf2a4c568e33aeaa 100644 +--- a/io/tst-fchmod-errors.c ++++ b/io/tst-fchmod-errors.c +@@ -18,8 +18,10 @@ + + #include + #include ++#include + #include + #include ++#include + + static int + do_test (void) +@@ -27,9 +29,14 @@ do_test (void) + { + /* Permissions on /dev/null (the opened descriptor) cannot be changed. */ + int fd = xopen ("/dev/null", O_RDWR, 0); +- errno = 0; +- TEST_COMPARE (fchmod (fd, 0), -1); +- TEST_COMPARE (errno, EPERM); ++ if (getuid () == 0) ++ puts ("info: /dev/null fchmod test skipped because of root privileges"); ++ else ++ { ++ errno = 0; ++ TEST_COMPARE (fchmod (fd, 0), -1); ++ TEST_COMPARE (errno, EPERM); ++ } + xclose (fd); + + /* Now testing an invalid file descriptor. */ diff --git a/glibc-RHEL-50548-3.patch b/glibc-RHEL-50548-3.patch new file mode 100644 index 0000000..e7d53f5 --- /dev/null +++ b/glibc-RHEL-50548-3.patch @@ -0,0 +1,149 @@ +commit 43669fcf7315f494bbbc2c040cedeb0fa8416a5f +Author: Florian Weimer +Date: Thu Aug 22 11:02:51 2024 +0200 + + io: Add FUSE-based test for fchmod + + Test all mode arguments, and that extra bits are ignored + as required by POSIX. + + Reviewed-by: DJ Delorie + +Conflicts: + io/Makefile + (usual tests conflict) + +diff --git a/io/Makefile b/io/Makefile +index 30dd48b8acf9dcb9..cc78a438a8898ae3 100644 +--- a/io/Makefile ++++ b/io/Makefile +@@ -80,7 +80,8 @@ tests := test-utime test-stat test-stat2 test-lfs tst-getcwd \ + tst-utimensat \ + tst-closefrom \ + tst-ftw-bz28126 \ +- tst-fchmod-errors ++ tst-fchmod-errors \ ++ tst-fchmod-fuse + + tests-time64 := \ + tst-fcntl-time64 \ +diff --git a/io/tst-fchmod-fuse.c b/io/tst-fchmod-fuse.c +new file mode 100644 +index 0000000000000000..fbd3309963491105 +--- /dev/null ++++ b/io/tst-fchmod-fuse.c +@@ -0,0 +1,114 @@ ++/* FUSE-based test for fchmod. ++ Copyright (C) 2024 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Set from do_test to indicate the expected incoming mode change request. */ ++static _Atomic int expected_mode; ++ ++static void ++fuse_thread (struct support_fuse *f, void *closure) ++{ ++ struct fuse_in_header *inh; ++ while ((inh = support_fuse_next (f)) != NULL) ++ { ++ if (support_fuse_handle_mountpoint (f) ++ || (inh->nodeid == 1 && support_fuse_handle_directory (f))) ++ continue; ++ switch (inh->opcode) ++ { ++ case FUSE_LOOKUP: ++ { ++ char *name = support_fuse_cast (LOOKUP, inh); ++ TEST_COMPARE_STRING (name, "file"); ++ struct fuse_entry_out *out ++ = support_fuse_prepare_entry (f, 2); ++ out->attr.mode = S_IFREG | 0600; ++ support_fuse_reply_prepared (f); ++ } ++ break; ++ case FUSE_OPEN: ++ { ++ TEST_COMPARE (inh->nodeid, 2); ++ struct fuse_open_in *p = support_fuse_cast (OPEN, inh); ++ TEST_COMPARE (p->flags & O_ACCMODE, O_RDWR); ++ struct fuse_open_out out = { 0, }; ++ support_fuse_reply (f, &out, sizeof (out)); ++ } ++ break; ++ case FUSE_SETATTR: ++ { ++ TEST_COMPARE (inh->nodeid, 2); ++ struct fuse_setattr_in *p = support_fuse_cast (SETATTR, inh); ++ TEST_COMPARE (p->valid , FATTR_MODE); ++ TEST_COMPARE (p->mode, S_IFREG | expected_mode); ++ struct fuse_attr_out *out = support_fuse_prepare_attr (f); ++ out->attr.mode = S_IFREG | p->mode; ++ support_fuse_reply_prepared (f); ++ } ++ break; ++ case FUSE_FLUSH: ++ support_fuse_reply_empty (f); ++ break; ++ default: ++ support_fuse_reply_error (f, EIO); ++ } ++ } ++} ++ ++/* Test all mode values with the specified extra bits. */ ++static void ++test_with_bits (int fd, unsigned int extra_bits) ++{ ++ for (int do_mode = 0; do_mode <= 07777; ++do_mode) ++ { ++ expected_mode = do_mode; ++ TEST_COMPARE (fchmod (fd, extra_bits | do_mode), 0); ++ } ++} ++ ++static int ++do_test (void) ++{ ++ support_fuse_init (); ++ ++ struct support_fuse *f = support_fuse_mount (fuse_thread, NULL); ++ char *path = xasprintf ("%s/file", support_fuse_mountpoint (f)); ++ int fd = xopen (path, O_RDWR, 0600); ++ free (path); ++ ++ test_with_bits (fd, 0); ++ /* POSIX requires that the extra bits are ignored. */ ++ test_with_bits (fd, S_IFREG); ++ test_with_bits (fd, S_IFDIR); ++ test_with_bits (fd, ~07777); ++ ++ xclose (fd); ++ support_fuse_unmount (f); ++ ++ return 0; ++} ++ ++#include diff --git a/glibc.spec b/glibc.spec index 82e93b8..ca3dfa9 100644 --- a/glibc.spec +++ b/glibc.spec @@ -157,7 +157,7 @@ end \ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 140%{?dist} +Release: 141%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -928,6 +928,9 @@ Patch689: glibc-RHEL-46736-8.patch Patch690: glibc-RHEL-46736-9.patch Patch691: glibc-RHEL-46736-10.patch Patch692: glibc-RHEL-46736-11.patch +Patch693: glibc-RHEL-50548-1.patch +Patch694: glibc-RHEL-50548-2.patch +Patch695: glibc-RHEL-50548-3.patch ############################################################################## # Continued list of core "glibc" package information: @@ -3087,6 +3090,9 @@ update_gconv_modules_cache () %endif %changelog +* Mon Nov 11 2024 Arjun Shankar - 2.34-141 +- Add error and FUSE based tests for fchmod (RHEL-50548) + * Thu Nov 7 2024 Florian Weimer - 2.34-140 - Add more tests for freopen (RHEL-46736)