From 797dd115249a0be204566569346dbc51157b5e28 Mon Sep 17 00:00:00 2001 From: dongshengyuan <545258830@qq.com> Date: Wed, 15 Jul 2026 16:38:07 +0800 Subject: [PATCH] portable: keep unit symlinks inside the image Open unit files with chase_and_openat() rooted at the image instead of plain openat(). Symlinks are now resolved under the image root and must end at a regular file. Reproducer: ln -s /tmp/portable-host-unit \ IMAGE/usr/lib/systemd/system/PREFIX.service portablectl inspect --cat IMAGE PREFIX.service Before: inspect followed the absolute symlink on the host and printed host file contents as image unit metadata. Image inspection could leak or trust files outside the portable image. Follow-up: 61d0578b07b97cbffebfd350bac481274e310d39 --- src/portable/portable.c | 10 ++++++++-- test/units/TEST-29-PORTABLE.directory.sh | 8 ++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/portable/portable.c b/src/portable/portable.c index d49c8a76b5..f0af728d48 100644 --- a/src/portable/portable.c +++ b/src/portable/portable.c @@ -392,9 +392,15 @@ static int extract_now( if (!IN_SET(de->d_type, DT_LNK, DT_REG)) continue; - fd = openat(dirfd(d), de->d_name, O_CLOEXEC|O_RDONLY); + fd = chase_and_openat( + rfd, + dirfd(d), + de->d_name, + CHASE_MUST_BE_REGULAR, + O_RDONLY|O_CLOEXEC, + /* ret_path= */ NULL); if (fd < 0) { - log_debug_errno(errno, "Failed to open unit file '%s', ignoring: %m", de->d_name); + log_debug_errno(fd, "Failed to open unit file '%s', ignoring: %m", de->d_name); continue; } diff --git a/test/units/TEST-29-PORTABLE.directory.sh b/test/units/TEST-29-PORTABLE.directory.sh index e6aafcb6af..1cedeea72b 100755 --- a/test/units/TEST-29-PORTABLE.directory.sh +++ b/test/units/TEST-29-PORTABLE.directory.sh @@ -24,6 +24,14 @@ rm -rf /tmp/mismatched-name cp -a /tmp/minimal_0 /tmp/mismatched-name portablectl inspect /tmp/mismatched-name | grep -F "minimal-app0.service" >/dev/null +rm -rf /tmp/symlink-unit +cp -a /tmp/minimal_0 /tmp/symlink-unit +printf '[Service]\nExecStart=/bin/true\n' >/tmp/portable-host-unit +rm -f /tmp/symlink-unit/usr/lib/systemd/system/minimal-app0.service +ln -s /tmp/portable-host-unit /tmp/symlink-unit/usr/lib/systemd/system/minimal-app0.service +(! portablectl inspect --cat /tmp/symlink-unit minimal-app0.service) +rm -f /tmp/portable-host-unit + portablectl "${ARGS[@]}" attach --copy=symlink --now --runtime /tmp/minimal_0 minimal-app0 systemctl is-active minimal-app0.service