machined: gate metadata querying behind inspect-machines/images action

Ensure only privileged users can call the system scope machined's
APIs that get data out of a machine

Follow-up for 1bd979dddb
Follow-up for 9153b02bb5
This commit is contained in:
Luca Boccassi
2026-04-16 13:29:33 +02:00
committed by Zbigniew Jędrzejewski-Szmek
parent 4efb5d389c
commit 3e716178cc
4 changed files with 87 additions and 1 deletions
+19
View File
@@ -247,6 +247,25 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s
assert(message);
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = {
"machine", m->name,
"verb", "get_os_release",
NULL
};
r = bus_verify_polkit_async(
message,
"org.freedesktop.machine1.inspect-machines",
details,
&m->manager->polkit_registry,
error);
if (r < 0)
return r;
if (r == 0)
return 1; /* Will call us back */
}
r = machine_get_os_release(m, &l);
if (r == -ENONET)
return sd_bus_error_set(error, SD_BUS_ERROR_FAILED, "Machine does not contain OS release information.");
+22
View File
@@ -535,6 +535,17 @@ static int vl_method_list(sd_varlink *link, sd_json_variant *parameters, sd_varl
if (r != 0)
return r;
if (m->runtime_scope != RUNTIME_SCOPE_USER && should_acquire_metadata(p.acquire_metadata)) {
r = varlink_verify_polkit_async(
link,
m->system_bus,
"org.freedesktop.machine1.inspect-machines",
(const char**) STRV_MAKE("name", strna(p.name)),
&m->polkit_registry);
if (r <= 0)
return r;
}
r = sd_varlink_set_sentinel(link, VARLINK_ERROR_MACHINE_NO_SUCH_MACHINE);
if (r < 0)
return r;
@@ -682,6 +693,17 @@ static int vl_method_list_images(sd_varlink *link, sd_json_variant *parameters,
if (r != 0)
return r;
if (m->runtime_scope != RUNTIME_SCOPE_USER && should_acquire_metadata(p.acquire_metadata)) {
r = varlink_verify_polkit_async(
link,
m->system_bus,
"org.freedesktop.machine1.inspect-images",
(const char**) STRV_MAKE("name", strna(p.image_name)),
&m->polkit_registry);
if (r <= 0)
return r;
}
r = sd_varlink_set_sentinel(link, VARLINK_ERROR_MACHINE_IMAGE_NO_SUCH_IMAGE);
if (r < 0)
return r;
+22 -1
View File
@@ -88,7 +88,17 @@
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.shell org.freedesktop.login1.login</annotate>
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.login1.shell org.freedesktop.login1.login org.freedesktop.machine1.inspect-machines</annotate>
</action>
<action id="org.freedesktop.machine1.inspect-machines">
<description gettext-domain="systemd">Inspect local virtual machines and containers</description>
<message gettext-domain="systemd">Authentication is required to inspect local virtual machines and containers.</message>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
<action id="org.freedesktop.machine1.create-machine">
@@ -120,6 +130,17 @@
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.imply">org.freedesktop.machine1.inspect-images</annotate>
</action>
<action id="org.freedesktop.machine1.inspect-images">
<description gettext-domain="systemd">Inspect local virtual machine and container images</description>
<message gettext-domain="systemd">Authentication is required to inspect local virtual machine and container images.</message>
<defaults>
<allow_any>auth_admin</allow_any>
<allow_inactive>auth_admin</allow_inactive>
<allow_active>auth_admin_keep</allow_active>
</defaults>
</action>
</policyconfig>
+24
View File
@@ -23,6 +23,8 @@ at_exit() {
rm -rf /home/testuser/.local/state/machines/inodetest2 ||:
rm -rf /home/testuser/.local/state/machines/mangletest ||:
machinectl terminate zurps ||:
machinectl terminate exfiltrate ||:
systemctl --user --machine testuser@ stop exfiltrate.service ||:
rm -f /etc/polkit-1/rules.d/registermachinetest.rules
machinectl terminate nurps ||:
machinectl terminate kurps ||:
@@ -163,6 +165,28 @@ run0 -u testuser \
systemctl --user --machine testuser@ stop sleep.service
test ! -f /shouldnotwork
echo FOO=bar >/tmp/foo
chmod 600 /tmp/foo
run0 -u testuser \
systemd-run --unit exfiltrate.service --service-type notify --property NotifyAccess=all --user \
unshare --map-root-user --user --mount \
bash -c 'mount --bind /tmp/foo /usr/lib/os-release; systemd-notify --ready; exec sleep infinity'
exfiltrate_pid="$(systemctl --machine testuser@.host show --user -P MainPID exfiltrate.service)"
run0 -u testuser \
varlinkctl \
call \
/run/systemd/machine/io.systemd.Machine \
io.systemd.Machine.Register \
"{\"name\":\"exfiltrate\", \"class\":\"container\", \"leader\": $exfiltrate_pid}"
exfiltrate_output="$(run0 -u testuser \
varlinkctl \
call \
/run/systemd/machine/io.systemd.Machine io.systemd.Machine.List \
"{\"name\":\"exfiltrate\",\"acquireMetadata\":\"graceful\"}" 2>&1)" || true
(! echo "$exfiltrate_output" | grep '"name".*"exfiltrate"' >/dev/null)
(! echo "$exfiltrate_output" | grep "FOO=bar" >/dev/null)
systemctl --user --machine testuser@ stop exfiltrate.service
run0 -u testuser mkdir /var/tmp/image-tar
run0 -u testuser importctl --user export-tar zurps /var/tmp/image-tar/kurps.tar.gz -m
run0 -u testuser importctl --user import-tar /var/tmp/image-tar/kurps.tar.gz -m