5 ms·
PolicyKit: Users with UID greater than INT_MAX can execute any systemctl command
- pjmlp 8y agoTypical exploit with unsigned/signed conversions. https://gitlab.freedesktop.org/polkit/polkit/issues/74 https://gitlab.freedesktop.org/polkit/polkit/issues/74
- CaliforniaKarl 8y agoParticularly 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.
- emmelaich 8y agoYou'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.
- JdeBP 8y agoIncorrect; nobody was 65534.
- emmelaich 8y agoD'oh! I knew I'd get it wrong. Thanks for the correction.
- kijin 8y agoWas the special treatment of -1 intended by the developers, or did somebody mix up signed -1 with unsigned 65535?
- emmelaich 8y agoSee above - it was -2 or 65534. I think -2 is just easier to type and stands out more.
- jabl 8y agoIn 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
- JdeBP 8y agoSee https://superuser.com/a/706578/38062 https://superuser.com/a/706578/38062 .
- mschuster91 8y ago> You'd have to be a privileged user to create such high uid user. Or use a broken / misconfigured AD/LDAP to sync uid/gid across a pool of machines.
- userbinator 8y ago...which implies already having high privileges. (How do users with such high UIDs come into existence?)
- jaxtellerSoA 8y ago>which implies already having high privileges. (How do users with such high UIDs come into existence?) I am not so sure about that. I work at a smallish, place and by default my AD account has UID of 945004649. Still under the INT_MAX but not that far off. Our domain controller is running Windows 2012 R2, and nothing was changed or touched regarding UID's, everything was left at the default. We just create users and get whatever UID AD assigns.
- pixl97 8y agoActive directory integration into Linux. Default numbers in the config files are very large.
- LinuxBender 8y agoThis could happen anywhere. If you know that dynamically created users are in range {x} and AD/LDAP users are in range {y}, then a good sysadmin would choose a very high range for batch creations of specific types of accounts. This is fairly common practice. Modern Linux and Windows can support millions of UID's, so it is perfectly reasonable to say, "We are going to use range {y} for this project then nuke that entire range when we are done".
- jabl 8y agoOthers pointed out that nobody was (uint16_t) -2, or 65534. But, it turns out this value is, in fact, special in current day Linux as well. It's the default value of the special 'overflow' uid, can be seen/set at /proc/sys/fs/overflowuid. Apart from some legacy stuff using 16-bit uid's, today it's mostly used for two things 1) In NFS, if mapping a user fails, then it gets assigned the overflowuid. 2) In containers with user namespaces, unmapped users again get the overflowuid. For more details, see https://lwn.net/Articles/695478/ https://lwn.net/Articles/695478/
- emmelaich 8y agoVery interesting, thanks.
- zaarn 8y agoIt 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 8y agoext4 for example only supports 32bit UIDs Unsigned or signed? That seems to be the critical difference here.
- gerdesj 8y agoI'm no C programmer but these looks like hints: 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 https://github.com/torvalds/linux/blob/master/fs/ext4/ext4.h...
- opless 8y agoAccording to this[1] NIS+ Probably allows it, so there's probably a nice multi-step attack possible... [1] https://docs.oracle.com/cd/E19620-01/805-3727/userconcept-3/index.html https://docs.oracle.com/cd/E19620-01/805-3727/userconcept-3/...
- jstimpfle 8y agoWhy 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 8y agoThis 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/14 https://gitlab.freedesktop.org/polkit/polkit/merge_requests/... We have been down this road before with assertions. * https://news.ycombinator.com/item?id=12655048 https://news.ycombinator.com/item?id=12655048
- Vogtinator 8y ago> causing pkttyagent to abend with an assertion failure, and then the authorization mechanism fails open Wrong. pkttyagent is just a frontend, it does not do any authorization itself. That's up to polkitd.
- JdeBP 8y agoI didn't say that pkttyagent was the authorization mechanism. I said that the authorization mechanism fails open after pkttyagent abends. M. Poettering looked at it with a Desktop Bus monitor to inspect the transaction. * https://github.com/systemd/systemd/issues/11026#issuecomment-443506247 https://github.com/systemd/systemd/issues/11026#issuecomment...
- dustfinger 8y agoYah, 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
- LinuxBender 8y agoHas 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 8y agoNobody 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 8y agoYou 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 8y agoTrue, 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.
- LinuxBender 8y agoFWIW, it looks like Redhat actually fixed the rpm dependencies and you can remove polkit without breaking systemd now.