Skip to content

Commit

Permalink
Fix sbit removal if fchmodat() doesn't support AT_SYMLINK_NOFOLLOW
Browse files Browse the repository at this point in the history
glibc versions prior to 2020 know about AT_SYMLINK_NOFOLLOW but don't
actually implement it for fchmodat() and returns ENOSYS when used.
We don't check the return code in removeSBITS() so this silently fails
on those older versions.

We already verify the thing is not a link in the fstatat() condition
because cap_set_fileat() doesn't have any "dont follow" mode at all,
so we can just as well drop it from the fchmodat() and make this
work on more libc versions.

Add a test for the suid bit removal while at it.
  • Loading branch information
pmatilai committed Nov 10, 2023
1 parent e3ab8a9 commit 3698b4c
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
3 changes: 2 additions & 1 deletion lib/fsm.c
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,9 @@ static void removeSBITS(int dirfd, const char *path)
struct stat stb;
int flags = AT_SYMLINK_NOFOLLOW;
if (fstatat(dirfd, path, &stb, flags) == 0 && S_ISREG(stb.st_mode)) {
/* We now know it's not a link so no need to worry about following */
if ((stb.st_mode & 06000) != 0) {
(void) fchmodat(dirfd, path, stb.st_mode & 0777, flags);
(void) fchmodat(dirfd, path, stb.st_mode & 0777, 0);
}
#ifdef WITH_CAP
if (stb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) {
Expand Down
22 changes: 22 additions & 0 deletions tests/rpme.at
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,28 @@ missing d /usr/share/doc/hello-2.0/README
[])
RPMTEST_CLEANUP

AT_SETUP([rpm -e suid hardlink])
AT_KEYWORDS([install erase])
RPMDB_INIT

runroot rpmbuild -bb --quiet \
/data/SPECS/attrtest.spec
RPMTEST_CHECK([
# silence "user/group does not exist" messages
runroot rpm -U --nodeps /build/RPMS/noarch/attrtest-1.0-1.noarch.rpm 2> /dev/null
runroot_other ln /i/file /if
runroot_other test -u /if && echo suid
runroot rpm -e attrtest
runroot_other test -f /if && echo exists
runroot_other test -u /if && echo suid
],
[1],
[suid
exists
],
[])
RPMTEST_CLEANUP

AT_SETUP([rpm reinstall with shared files])
AT_KEYWORDS([install erase update rpmdb])
RPMDB_INIT
Expand Down

0 comments on commit 3698b4c

Please sign in to comment.