From: Lennart Poettering Date: Fri, 19 Oct 2018 09:28:40 +0000 (+0200) Subject: chown-recursive: also drop ACLs when recursively chown()ing X-Git-Tag: archive/raspbian/239-15+rpi1^2~33 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=84a3a744bb3edd4c23678a03d008ababdc2f77d9;p=systemd.git chown-recursive: also drop ACLs when recursively chown()ing Let's better be safe than sorry and also drop ACLs. (cherry picked from commit f89bc84f3242449cbc308892c87573b131f121df) Gbp-Pq: Name chown-recursive-also-drop-ACLs-when-recursively-chown-ing.patch --- diff --git a/src/core/chown-recursive.c b/src/core/chown-recursive.c index 27c64489..447b7712 100644 --- a/src/core/chown-recursive.c +++ b/src/core/chown-recursive.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "chown-recursive.h" #include "dirent-util.h" @@ -14,6 +15,7 @@ static int chown_one(int fd, const struct stat *st, uid_t uid, gid_t gid) { char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int) + 1]; + const char *n; assert(fd >= 0); assert(st); @@ -26,13 +28,19 @@ static int chown_one(int fd, const struct stat *st, uid_t uid, gid_t gid) { * O_PATH. (Note: fchown() and fchmod() do not work with O_PATH, the kernel refuses that. */ xsprintf(procfs_path, "/proc/self/fd/%i", fd); + /* Drop any ACL if there is one */ + FOREACH_STRING(n, "system.posix_acl_access", "system.posix_acl_default") + if (removexattr(procfs_path, n) < 0) + if (!IN_SET(errno, ENODATA, EOPNOTSUPP, ENOSYS, ENOTTY)) + return -errno; + if (chown(procfs_path, uid, gid) < 0) return -errno; - /* The linux kernel alters the mode in some cases of chown(). Let's undo this. We do this only for non-symlinks - * however. That's because for symlinks the access mode is ignored anyway and because on some kernels/file - * systems trying to change the access mode will succeed but has no effect while on others it actively - * fails. */ + /* The linux kernel alters the mode in some cases of chown(), as well when we change ACLs. Let's undo this. We + * do this only for non-symlinks however. That's because for symlinks the access mode is ignored anyway and + * because on some kernels/file systems trying to change the access mode will succeed but has no effect while + * on others it actively fails. */ if (!S_ISLNK(st->st_mode)) if (chmod(procfs_path, st->st_mode & 07777) < 0) return -errno;