diff options
author | Arseny Maslennikov <arseny@altlinux.org> | 2023-10-21 10:00:00 +0200 |
---|---|---|
committer | Mike Yuan <me@yhndnzj.com> | 2023-11-01 17:29:09 +0100 |
commit | 30462563b19b92d8c6ed196d30d3cf7de90e8131 (patch) | |
tree | adcc74f000d7720bb93dfbb9d8af51caa9c6e077 /src/nspawn | |
parent | basic/fs-util: prefer fchmodat2 in fchmod_opath (diff) | |
download | systemd-30462563b19b92d8c6ed196d30d3cf7de90e8131.tar.xz systemd-30462563b19b92d8c6ed196d30d3cf7de90e8131.zip |
nspawn-patch-uid: try fchmodat2() to restore mode of symlink
Prior to this commit, if the target had been a symlink, we did nothing
with it. Let's try with fchmodat2() and skip gracefully if not supported.
Co-authored-by: Mike Yuan <me@yhndnzj.com>
Diffstat (limited to 'src/nspawn')
-rw-r--r-- | src/nspawn/nspawn-patch-uid.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/src/nspawn/nspawn-patch-uid.c b/src/nspawn/nspawn-patch-uid.c index 66663adc2b..063995dd6b 100644 --- a/src/nspawn/nspawn-patch-uid.c +++ b/src/nspawn/nspawn-patch-uid.c @@ -11,6 +11,7 @@ #include "fileio.h" #include "fs-util.h" #include "missing_magic.h" +#include "missing_syscall.h" #include "nspawn-def.h" #include "nspawn-patch-uid.h" #include "stat-util.h" @@ -239,14 +240,18 @@ static int patch_fd(int fd, const char *name, const struct stat *st, uid_t shift /* The Linux kernel alters the mode in some cases of chown(). Let's undo this. */ if (name) { + /* It looks like older glibc (before 2016) did not support AT_SYMLINK_NOFOLLOW. */ if (!S_ISLNK(st->st_mode)) - r = fchmodat(fd, name, st->st_mode, 0); - else /* AT_SYMLINK_NOFOLLOW is not available for fchmodat() */ - r = 0; + r = RET_NERRNO(fchmodat(fd, name, st->st_mode, 0)); + else { + r = RET_NERRNO(fchmodat2(fd, name, st->st_mode, AT_SYMLINK_NOFOLLOW)); + if (IN_SET(r, -ENOSYS, -EPERM)) + r = 0; + } } else - r = fchmod(fd, st->st_mode); + r = RET_NERRNO(fchmod(fd, st->st_mode)); if (r < 0) - return -errno; + return r; changed = true; } |