tmpfiles: keep directory specifiers rootless

%t and the other directory specifiers are parsed as normal paths.
They are prefixed by --root= later, so the specifier itself must stay
rootless.

Reproducer:
  tmp=$(mktemp -d /tmp/tmpfiles-root.XXXXXX)
  conf=$(mktemp /tmp/tmpfiles-conf.XXXXXX)
  printf 'd %%t/tmpfiles-repro 0755 - - -\n' >"$conf"
  systemd-tmpfiles --root="$tmp" --create --dry-run "$conf"

Before:
  Would create directory $tmp/$tmp/run/tmpfiles-repro

Follow-up for de61a04b18.
This commit is contained in:
dongshengyuan
2026-07-23 14:33:16 +08:00
parent d751846043
commit 58496809c0
2 changed files with 13 additions and 10 deletions
+1 -10
View File
@@ -322,16 +322,7 @@ static int specifier_directory(
if (r < 0)
return r;
if (arg_root) {
_cleanup_free_ char *j = NULL;
j = path_join(arg_root, p);
if (!j)
return -ENOMEM;
*ret = TAKE_PTR(j);
} else
*ret = TAKE_PTR(p);
*ret = TAKE_PTR(p);
return 0;
}
+12
View File
@@ -42,3 +42,15 @@ systemd-tmpfiles --create --root="$root" - <<EOF
L %h - - - -
EOF
test "$(readlink "$dst")" = "$src"
# Check that directory specifiers are not prefixed with --root twice.
root='/tmp/L/3'
rm -rf "$root"
mkdir -p "$root"
output="$(systemd-tmpfiles --create --dry-run --root="$root" - 2>&1 <<EOF
d %t/test - - - -
EOF
)"
[[ "$output" == *"Would create directory $root/run/test"* ]]
[[ "$output" != *"$root$root"* ]]