
PolicyKit: Users with UID greater than INT_MAX can execute any systemctl command - fridsun
https://gitlab.freedesktop.org/polkit/polkit/issues/74
======
CaliforniaKarl
Particularly worth noting because systemd uses polkit, so certain unprivileged
users can do systemctl commands that only admins should be able to do.

See also
[https://github.com/systemd/systemd/issues/11026](https://github.com/systemd/systemd/issues/11026)

But this isn’t a systemd bug, this is a bug in software systemd relies on.

------
pjmlp
Typical exploit with unsigned/signed conversions.

[https://gitlab.freedesktop.org/polkit/polkit/issues/74](https://gitlab.freedesktop.org/polkit/polkit/issues/74)

------
emmelaich
You'd have to be a privileged user to create such high uid user.

And it's very unlikely to happen by accident, right? So can't get too excited
about this.

Bit of trivia - one some older Unixes (HP-UX) the uid -1 was special - was
always unprivileged 'nobody' and was equal to 65535.

~~~
kijin
Was the special treatment of -1 intended by the developers, or did somebody
mix up signed -1 with unsigned 65535?

~~~
jabl
In POSIX, many functions return -1 to indicate errors. So I guess the value
(uid_t) -1 was reserved to avoid confusion. Also some functions (chown())
allow specifying (uid_t) -1 or (gid_) -1 to mark an omitted argument.

See
[https://en.wikipedia.org/wiki/User_identifier#Special_values](https://en.wikipedia.org/wiki/User_identifier#Special_values)

------
zaarn
It should be noted that with a UID larger than INT_MAX a lot of things will
start to break, ext4 for example only supports 32bit UIDs, so you won't be
able to chown any files as this UID (atleast my own experimentation seems to
find this. NFSv4 allows it if you enable squashing/mapping of user ids).

Lots of other tools will likely break in similar and unpredictable ways if
your UID becomes that high. Likely those ways are also a lot of fun.

Since you'd need to be a privileged user to begin with, this is on the same
alarm level as "running sed with sudo allows you to edit /etc/sudoers and gain
full sudo privilege".

~~~
userbinator
_ext4 for example only supports 32bit UIDs_

Unsigned or signed? That seems to be the critical difference here.

~~~
gerdesj
I'm no C programmer but these looks like hints:

[https://github.com/torvalds/linux/blob/master/fs/ext4/ext4.h...](https://github.com/torvalds/linux/blob/master/fs/ext4/ext4.h#L689)

[https://github.com/torvalds/linux/blob/master/fs/ext4/ext4.h...](https://github.com/torvalds/linux/blob/master/fs/ext4/ext4.h#L1105)

------
jstimpfle
Why don't we have hardware overflow traps? Most numbers should never overflow.
We would need just 1 additional bit for arithmetic instructions to indicate
that overflows are fine in some cases.

~~~
JdeBP
This is not an overflow problem. PolicyKit is deciding to exclude negative
numbers from the allowable range of user IDs, causing pkttyagent to abend with
an assertion failure, _and then the authorization mechanism fails open_.

The proposed patch from the systemd developers, somewhat worryingly,
apparently does not address the failing open. It simply stops PolicyKit from
excluding negative numbers as UIDs, and thus the assertion from failing. The
worry is that some _other_ assertion might trigger in the agent, or be
introduced, that causes it to fail open in some other way. _It should fail
closed._

* [https://gitlab.freedesktop.org/polkit/polkit/merge_requests/...](https://gitlab.freedesktop.org/polkit/polkit/merge_requests/14)

We have been down this road before with assertions.

* [https://news.ycombinator.com/item?id=12655048](https://news.ycombinator.com/item?id=12655048)

~~~
dustfinger
Yah, the title is technically not accurate since 2*(INT_MAX -1) overflows, is
not negative and cannot run arbitrary systemctl commands (I have not tested
though). The title would have been clear if it had read:

> unprivileged users with negative UID can successfully execute any systemctl
> command

~~~
dustfinger
I was wrong. You can create UID greater than int_max. The problem happens in a
policy kit assertion. pjmlp linked the policy kit issue #74 (thanks).

------
LinuxBender
Has anyone found a clean way to remove polkit once installed without breaking
systemd? On Redhat at least, you have to kickstart the machine without
anything that pulls it in. It can't be "disabled" without breaking things and
udev will trigger it regardless of the unit file state.

~~~
LinuxBender
Nobody on serverfault could find a way either. Most of my stuff is Alpine
Linux (non-systemd) so not a big issue. At work, we have a lot of CentOS and I
just advise folks to keep their kickstart minimal to avoid pulling in polkit.

~~~
JdeBP
You will have the problem whether or not your system has systemd. It exists in
PolicyKit on FreeBSD, for example.

    
    
        # setuidgid sint32maxp1 id
        uid=2147483648(sint32maxp1) gid=2147483648 groups=2147483648
        # setuidgid sint32maxp1 pkexec id
    
        (process:99600): GLib-GObject-WARNING **: value "-2147483648" of type 'gint' is invalid or out of range for property 'uid' of type 'gint'
        uid=0(root) gid=0(wheel) groups=0(wheel),5(operator)
        #

~~~
LinuxBender
True, but on systems without systemd, I have never seen PolicyKit get
installed without explicitly requesting it. On systems with systemd, there are
many packages that cause it to get pulled in. Mostly desktop packages, but
there are some used on both server and desktop that pollute servers with
desktop behavior now, due to the integration in systemd.

