portabled: authenticate extension images specified by path

GetImageMetadata() and GetImageMetadataWithExtensions() ask polkit before
inspecting an image that is specified by path, because inspecting
loop-mounts the image as root. Extension images aren't authenticated at
all, so any local user can make portabled set up loop devices for files
they choose, probe them and mount them, by passing them as extensions of
an installed image.

Let's ask polkit for the inspect-images action if any extension image is
specified by path, like we do for the image itself.

(cherry picked from commit 5ddab5b8f4)
(cherry picked from commit 38ab8023a5)
This commit is contained in:
Daan De Meyer authored and Luca Boccassi committed 2026-11-05 14:30:22 +00:00
1 parent 648de3d8f1
commit 8e39ee06c8
2 files changed
+29 -1

No files matched your search

+10 -1
View File
@@ -145,11 +145,20 @@ int bus_image_common_get_metadata(
flags |= input_flags;
}
/* Inspecting an image loop-mounts it as root, so we authenticate extension images that are
* specified by path like the image itself. */
bool extension_by_path = false;
STRV_FOREACH(i, extension_images)
if (!image_name_is_valid(*i)) {
extension_by_path = true;
break;
}
r = bus_image_acquire(m,
message,
name_or_path,
image,
BUS_IMAGE_AUTHENTICATE_BY_PATH,
extension_by_path ? BUS_IMAGE_AUTHENTICATE_ALL : BUS_IMAGE_AUTHENTICATE_BY_PATH,
"org.freedesktop.portable1.inspect-images",
&image,
error);
+19
View File
@@ -17,6 +17,25 @@ if [[ -v ASAN_OPTIONS || -v UBSAN_OPTIONS ]]; then
ARGS+=(--profile=trusted)
fi
# Unprivileged users can inspect images and extension images by name, but not extension images specified by
# path, because inspecting loop-mounts the extension images as root.
mkdir -p /run/portables
cp /usr/share/minimal_0.raw /run/portables/minimal_8.raw
cp /tmp/app0.raw /run/portables/app0.raw
runas testuser busctl call org.freedesktop.portable1 /org/freedesktop/portable1 org.freedesktop.portable1.Manager \
GetImageMetadata sas minimal_8 0 >/dev/null
runas testuser busctl call org.freedesktop.portable1 /org/freedesktop/portable1 org.freedesktop.portable1.Manager \
GetImageMetadataWithExtensions sasast minimal_8 1 app0 0 0 >/dev/null
# portabled fails with "Permission denied" if polkit denies the call. It fails with a message that starts with
# "Access denied" if polkit requires interactive authentication.
(! runas testuser busctl call org.freedesktop.portable1 /org/freedesktop/portable1 org.freedesktop.portable1.Manager \
GetImageMetadataWithExtensions sasast minimal_8 1 /tmp/app0.raw 0 0 2>&1 >/dev/null) |
grep -E "Permission denied|Access denied" >/dev/null
(! runas testuser busctl call org.freedesktop.portable1 /org/freedesktop/portable1/image/minimal_5f8 org.freedesktop.portable1.Image \
GetMetadataWithExtensions asast 1 /tmp/app0.raw 0 0 2>&1 >/dev/null) |
grep -E "Permission denied|Access denied" >/dev/null
rm /run/portables/minimal_8.raw /run/portables/app0.raw
# Attaching with a profile that doesn't exist must fail and must not leave anything behind
(! portablectl attach --runtime --profile=nonexistent /usr/share/minimal_0.raw minimal-app0)
test ! -e /run/systemd/system.attached/minimal-app0.service