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
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;
}
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