[systemd-devel] Unprivileged poweroff

Simon McVittie simon.mcvittie at collabora.co.uk
Wed Sep 10 08:10:36 PDT 2014


On 10/09/14 15:03, Michal Witanowski wrote:
> I was wondering if there is a possibility to call “systemctl poweroff”
> as non-root user [without PolicyKit or sudo]
...
> Theoretically there is no other way, am I right?

If you want to escalate privileges in a controlled way, you need a
controlled privilege-escalation tool. PolicyKit is one such tool;
systemctl is another; a setuid binary written by you, which takes all
the necessary steps to to sanitize its environment and then invokes
"systemctl poweroff" or the equivalent D-Bus call, is another possibility.

> But what about CAP_SYS_BOOT? Does the systemctl shouldn’t verify if this
> capability is set and allow non-root user to shut down the system?

systemctl isn't magic, it just sends a D-Bus message to systemd. You can
reimplement it with any D-Bus implementation.

D-Bus is basically built on top of Unix sockets (until kdbus or
something similar arrives in the kernel) and Unix sockets do not have
any safe way[1] to prove to the remote process that you have access to
CAP_SYS_BOOT. The only things you can prove are that you had a specified
uid/pid/gid when you opened the socket (SO_PEERCRED, SCM_CREDENTIALS),
that you had a specified SELinux/Smack label (SCM_SECURITY), and that
you have access to a particular file descriptor now (SCM_RIGHTS).

Regards,
    S

[1] the unsafe way is to prove that you have a particular pid, then
rummage in /proc to find out more about that pid; the existence of
exec() and the fact that pids wrap around both provide a race condition
that could be used to escalate privileges if anything relies on that
information for security decisions



More information about the systemd-devel mailing list