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: 61d0578b07
This commit is contained in:
dongshengyuan
2026-07-15 18:16:29 +08:00
parent 57c64f7c69
commit 797dd11524
2 changed files with 16 additions and 2 deletions
+8 -2
View File
@@ -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;
}
+8
View File
@@ -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