tmpfiles: do not follow copy source symlinks

C lines copy symlinks as symlinks. The post-copy type check should
inspect the source symlink itself, not follow its target.

Reproducer:
  src=/tmp/tmpfiles-src-link.$$
  dst=/tmp/tmpfiles-dst-link.$$
  conf=/tmp/tmpfiles-conf.$$
  ln -s missing-target "$src"
  printf 'C %s - - - - %s\n' "$dst" "$src" >"$conf"
  systemd-tmpfiles --create "$conf"

Before:
  Failed to stat($src): No such file or directory
  status=73
  $dst -> missing-target already existed

Follow-up for 8f6fb95cd0.
This commit is contained in:
dongshengyuan
2026-07-23 19:33:08 +08:00
parent f936c9b366
commit c56420a362
2 changed files with 11 additions and 2 deletions
+2 -2
View File
@@ -2249,8 +2249,8 @@ static int copy_files(Context *c, Item *i) {
if (fstat(fd, &st) < 0)
return log_error_errno(errno, "Failed to fstat(%s): %m", i->path);
if (stat(i->argument, &a) < 0)
return log_error_errno(errno, "Failed to stat(%s): %m", i->argument);
if (lstat(i->argument, &a) < 0)
return log_error_errno(errno, "Failed to lstat(%s): %m", i->argument);
if (((st.st_mode ^ a.st_mode) & S_IFMT) != 0) {
log_debug("Can't copy to %s, file exists already and is of different type", i->path);
+9
View File
@@ -209,6 +209,15 @@ test ! -e /tmp/C-copy-failure-dst/file
chmod 755 /tmp/C-copy-failure-dst
rm -rf /tmp/C-copy-failure-src /tmp/C-copy-failure-dst
rm -f /tmp/C-copy-link-src /tmp/C-copy-link-dst
ln -s missing-target /tmp/C-copy-link-src
systemd-tmpfiles --create - <<EOF
C /tmp/C-copy-link-dst - - - - /tmp/C-copy-link-src
EOF
test -L /tmp/C-copy-link-dst
test "$(readlink /tmp/C-copy-link-dst)" = "missing-target"
rm -f /tmp/C-copy-link-src /tmp/C-copy-link-dst
#
# 'w'
#