summaryrefslogtreecommitdiffstats
path: root/src/nspawn
diff options
context:
space:
mode:
authorArseny Maslennikov <arseny@altlinux.org>2023-10-21 10:00:00 +0200
committerMike Yuan <me@yhndnzj.com>2023-11-01 17:29:09 +0100
commit30462563b19b92d8c6ed196d30d3cf7de90e8131 (patch)
treeadcc74f000d7720bb93dfbb9d8af51caa9c6e077 /src/nspawn
parentbasic/fs-util: prefer fchmodat2 in fchmod_opath (diff)
downloadsystemd-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.c15
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;
}