From: Lennart Poettering Date: Tue, 27 Jun 2023 09:09:03 +0000 (+0200) Subject: execute: when recursively chowning StateDirectory= when spawning services, follow... X-Git-Tag: v254-rc1~84^2~10 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=d5602c16324ec545c82bb59a3d60a349da7c370c;p=thirdparty%2Fsystemd.git execute: when recursively chowning StateDirectory= when spawning services, follow initial symlink It should be OK to allow one level of symlink for the various types of directories like StateDirectory=, LogsDirectory= and such. --- diff --git a/src/core/execute.c b/src/core/execute.c index bcd761b755a..11d707b59cf 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -2689,7 +2689,7 @@ static int setup_exec_directory( /* Then, change the ownership of the whole tree, if necessary. When dynamic users are used we * drop the suid/sgid bits, since we really don't want SUID/SGID files for dynamic UID/GID * assignments to exist. */ - r = path_chown_recursive(pp ?: p, uid, gid, context->dynamic_user ? 01777 : 07777); + r = path_chown_recursive(pp ?: p, uid, gid, context->dynamic_user ? 01777 : 07777, AT_SYMLINK_FOLLOW); if (r < 0) goto fail; } diff --git a/src/shared/chown-recursive.c b/src/shared/chown-recursive.c index 883c1ccee4e..6aa5f6723ec 100644 --- a/src/shared/chown-recursive.c +++ b/src/shared/chown-recursive.c @@ -111,12 +111,15 @@ int path_chown_recursive( const char *path, uid_t uid, gid_t gid, - mode_t mask) { + mode_t mask, + int flags) { _cleanup_close_ int fd = -EBADF; struct stat st; - fd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOFOLLOW|O_NOATIME); + assert((flags & ~AT_SYMLINK_FOLLOW) == 0); + + fd = open(path, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOATIME|(FLAGS_SET(flags, AT_SYMLINK_FOLLOW) ? 0 : O_NOFOLLOW)); if (fd < 0) return -errno; diff --git a/src/shared/chown-recursive.h b/src/shared/chown-recursive.h index 00038c3b325..2aab8e74142 100644 --- a/src/shared/chown-recursive.h +++ b/src/shared/chown-recursive.h @@ -3,6 +3,6 @@ #include -int path_chown_recursive(const char *path, uid_t uid, gid_t gid, mode_t mask); +int path_chown_recursive(const char *path, uid_t uid, gid_t gid, mode_t mask, int flags); int fd_chown_recursive(int fd, uid_t uid, gid_t gid, mode_t mask); diff --git a/src/test/test-chown-rec.c b/src/test/test-chown-rec.c index 801b49f7b73..dcff17efec2 100644 --- a/src/test/test-chown-rec.c +++ b/src/test/test-chown-rec.c @@ -104,7 +104,7 @@ TEST(chown_recursive) { assert_se(st.st_gid == gid); assert_se(has_xattr(p)); - assert_se(path_chown_recursive(t, 1, 2, 07777) >= 0); + assert_se(path_chown_recursive(t, 1, 2, 07777, 0) >= 0); p = strjoina(t, "/dir"); assert_se(lstat(p, &st) >= 0);