mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-23 17:34:00 +03:00
Merge pull request #11820 from dm0-/chase
Allow tmpfiles to create files in a root under an unprivileged directory
This commit is contained in:
commit
46d4d67d79
@ -926,6 +926,7 @@ int chase_symlinks(const char *path, const char *original_root, unsigned flags,
|
||||
if (fstat(child, &st) < 0)
|
||||
return -errno;
|
||||
if ((flags & CHASE_SAFE) &&
|
||||
(empty_or_root(root) || (size_t)(todo - buffer) > strlen(root)) &&
|
||||
unsafe_transition(&previous_stat, &st))
|
||||
return log_unsafe_transition(fd, child, path, flags);
|
||||
|
||||
|
@ -154,6 +154,30 @@ static void test_chase_symlinks(void) {
|
||||
assert_se(path_equal(result, q));
|
||||
result = mfree(result);
|
||||
|
||||
/* Paths underneath the "root" with different UIDs while using CHASE_SAFE */
|
||||
|
||||
if (geteuid() == 0) {
|
||||
p = strjoina(temp, "/user");
|
||||
assert_se(mkdir(p, 0755) >= 0);
|
||||
assert_se(chown(p, UID_NOBODY, GID_NOBODY) >= 0);
|
||||
|
||||
q = strjoina(temp, "/user/root");
|
||||
assert_se(mkdir(q, 0755) >= 0);
|
||||
|
||||
p = strjoina(q, "/link");
|
||||
assert_se(symlink("/", p) >= 0);
|
||||
|
||||
/* Fail when user-owned directories contain root-owned subdirectories. */
|
||||
r = chase_symlinks(p, temp, CHASE_SAFE, &result);
|
||||
assert_se(r == -ENOLINK);
|
||||
result = mfree(result);
|
||||
|
||||
/* Allow this when the user-owned directories are all in the "root". */
|
||||
r = chase_symlinks(p, q, CHASE_SAFE, &result);
|
||||
assert_se(r > 0);
|
||||
result = mfree(result);
|
||||
}
|
||||
|
||||
/* Paths using . */
|
||||
|
||||
r = chase_symlinks("/etc/./.././", NULL, 0, &result);
|
||||
|
@ -856,7 +856,7 @@ static int path_open_parent_safe(const char *path) {
|
||||
if (!dn)
|
||||
return log_oom();
|
||||
|
||||
fd = chase_symlinks(dn, NULL, CHASE_OPEN|CHASE_SAFE|CHASE_WARN, NULL);
|
||||
fd = chase_symlinks(dn, arg_root, CHASE_OPEN|CHASE_SAFE|CHASE_WARN, NULL);
|
||||
if (fd < 0 && fd != -ENOLINK)
|
||||
return log_error_errno(fd, "Failed to validate path %s: %m", path);
|
||||
|
||||
@ -877,7 +877,7 @@ static int path_open_safe(const char *path) {
|
||||
"Failed to open invalid path '%s'.",
|
||||
path);
|
||||
|
||||
fd = chase_symlinks(path, NULL, CHASE_OPEN|CHASE_SAFE|CHASE_WARN|CHASE_NOFOLLOW, NULL);
|
||||
fd = chase_symlinks(path, arg_root, CHASE_OPEN|CHASE_SAFE|CHASE_WARN|CHASE_NOFOLLOW, NULL);
|
||||
if (fd < 0 && fd != -ENOLINK)
|
||||
return log_error_errno(fd, "Failed to validate path %s: %m", path);
|
||||
|
||||
@ -2256,7 +2256,7 @@ static int process_item(Item *i, OperationMask operation) {
|
||||
|
||||
i->done |= operation;
|
||||
|
||||
r = chase_symlinks(i->path, NULL, CHASE_NO_AUTOFS|CHASE_WARN, NULL);
|
||||
r = chase_symlinks(i->path, arg_root, CHASE_NO_AUTOFS|CHASE_WARN, NULL);
|
||||
if (r == -EREMOTE) {
|
||||
log_notice_errno(r, "Skipping %s", i->path);
|
||||
return 0;
|
||||
|
32
test/TEST-22-TMPFILES/test-08.sh
Executable file
32
test/TEST-22-TMPFILES/test-08.sh
Executable file
@ -0,0 +1,32 @@
|
||||
#! /bin/bash
|
||||
#
|
||||
# Verify tmpfiles can run in a root directory under a path prefix that contains
|
||||
# directories owned by unprivileged users, for example when a root file system
|
||||
# is mounted in a regular user's home directory.
|
||||
#
|
||||
# https://github.com/systemd/systemd/pull/11820
|
||||
#
|
||||
|
||||
set -e
|
||||
|
||||
rm -fr /tmp/root /tmp/user
|
||||
mkdir -p /tmp/root /tmp/user/root
|
||||
chown daemon:daemon /tmp/user
|
||||
|
||||
# Verify the command works as expected with no prefix or a root-owned prefix.
|
||||
echo 'd /tmp/root/test1' | systemd-tmpfiles --create -
|
||||
test -d /tmp/root/test1
|
||||
echo 'd /test2' | systemd-tmpfiles --root=/tmp/root --create -
|
||||
test -d /tmp/root/test2
|
||||
|
||||
# Verify the command fails to write to a root-owned subdirectory under an
|
||||
# unprivileged user's directory when it's not part of the prefix, as expected
|
||||
# by the unsafe_transition function.
|
||||
! echo 'd /tmp/user/root/test' | systemd-tmpfiles --create -
|
||||
! test -e /tmp/user/root/test
|
||||
! echo 'd /user/root/test' | systemd-tmpfiles --root=/tmp --create -
|
||||
! test -e /tmp/user/root/test
|
||||
|
||||
# Verify the above works when all user-owned directories are in the prefix.
|
||||
echo 'd /test' | systemd-tmpfiles --root=/tmp/user/root --create -
|
||||
test -d /tmp/user/root/test
|
Loading…
Reference in New Issue
Block a user