mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 00:47:10 +09:00
machine: do not allow unprivileged users to register other users' processes as machines
Registering a process as a machine means a caller can get machined
to send sigterm to it, and more. If an unpriv user is registering,
ensure the registered process is actually owned by the user.
Follow-up for adaff8eb35
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include "machine-varlink.h"
|
||||
#include "machined.h"
|
||||
#include "mount-util.h"
|
||||
#include "namespace-util.h"
|
||||
#include "operation.h"
|
||||
#include "pidref.h"
|
||||
#include "socket-util.h"
|
||||
@@ -186,6 +187,15 @@ int vl_method_register(sd_varlink *link, sd_json_variant *parameters, sd_varlink
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Ensure an unprivileged user cannot claim any process they don't control as their own machine */
|
||||
if (machine->uid != 0) {
|
||||
r = process_is_owned_by_uid(&machine->leader, machine->uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return sd_varlink_error(link, SD_VARLINK_ERROR_PERMISSION_DENIED, NULL);
|
||||
}
|
||||
|
||||
r = machine_link(manager, machine);
|
||||
if (r == -EEXIST)
|
||||
return sd_varlink_error(link, VARLINK_ERROR_MACHINE_EXISTS, NULL);
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "machine-dbus.h"
|
||||
#include "machine-pool.h"
|
||||
#include "machined.h"
|
||||
#include "namespace-util.h"
|
||||
#include "operation.h"
|
||||
#include "os-util.h"
|
||||
#include "path-util.h"
|
||||
@@ -321,6 +322,15 @@ static int method_create_or_register_machine(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* Ensure an unprivileged user cannot claim any process they don't control as their own machine */
|
||||
if (uid != 0) {
|
||||
r = process_is_owned_by_uid(&leader_pidref, uid);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0)
|
||||
return sd_bus_error_set(error, SD_BUS_ERROR_ACCESS_DENIED, "Only root may register machines for other users");
|
||||
}
|
||||
|
||||
const char *details[] = {
|
||||
"name", name,
|
||||
"class", machine_class_to_string(c),
|
||||
|
||||
@@ -15,7 +15,7 @@ fi
|
||||
at_exit() {
|
||||
rm -rf /home/testuser/.local/state/machines/zurps ||:
|
||||
machinectl terminate zurps ||:
|
||||
rm -f /usr/share/polkit-1/rules.d/registermachinetest.rules
|
||||
rm -f /etc/polkit-1/rules.d/registermachinetest.rules
|
||||
}
|
||||
|
||||
trap at_exit EXIT
|
||||
@@ -33,7 +33,8 @@ systemd-dissect --shift /home/testuser/.local/state/machines/zurps foreign
|
||||
|
||||
# Install a PK rule that allows 'testuser' user to register a machine even
|
||||
# though they are not on an fg console, just for testing
|
||||
cat >/usr/share/polkit-1/rules.d/registermachinetest.rules <<'EOF'
|
||||
mkdir -p /etc/polkit-1/rules.d
|
||||
cat >/etc/polkit-1/rules.d/registermachinetest.rules <<'EOF'
|
||||
polkit.addRule(function(action, subject) {
|
||||
if (action.id == "org.freedesktop.machine1.register-machine" &&
|
||||
subject.user == "testuser") {
|
||||
@@ -54,4 +55,18 @@ machinectl terminate zurps
|
||||
|
||||
(! run0 -u testuser systemctl is-active --user systemd-nspawn@zurps.service)
|
||||
|
||||
(! run0 -u testuser \
|
||||
busctl call \
|
||||
org.freedesktop.machine1 \
|
||||
/org/freedesktop/machine1 \
|
||||
org.freedesktop.machine1.Manager \
|
||||
RegisterMachine \
|
||||
'sayssus' \
|
||||
shouldnotwork1 \
|
||||
16 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 \
|
||||
"" \
|
||||
container \
|
||||
"$(systemctl show -p MainPID --value systemd-logind.service)" \
|
||||
"$PWD")
|
||||
|
||||
loginctl disable-linger testuser
|
||||
|
||||
Reference in New Issue
Block a user