Revert "nspawn-patch-uid: try fchmodat2() to restore mode of symlink"
authorMike Yuan <me@yhndnzj.com>
Sat, 25 Nov 2023 10:57:53 +0000 (18:57 +0800)
committerMike Yuan <me@yhndnzj.com>
Sat, 25 Nov 2023 11:12:15 +0000 (19:12 +0800)
This reverts commit 30462563b19b92d8c6ed196d30d3cf7de90e8131.

fchmodat2(), while accepting AT_SYMLINK_NOFOLLOW as a valid flag,
always returns EOPNOTSUPP when operating on a symlink. The Linux kernel
simply doesn't support changing the mode of a symlink.

Fixes #30157

src/nspawn/nspawn-patch-uid.c

index 063995d..66663ad 100644 (file)
@@ -11,7 +11,6 @@
 #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"
@@ -240,18 +239,14 @@ 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 = 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;
-                        }
+                                r = fchmodat(fd, name, st->st_mode, 0);
+                        else /* AT_SYMLINK_NOFOLLOW is not available for fchmodat() */
+                                r = 0;
                 } else
-                        r = RET_NERRNO(fchmod(fd, st->st_mode));
+                        r = fchmod(fd, st->st_mode);
                 if (r < 0)
-                        return r;
+                        return -errno;
 
                 changed = true;
         }