A privilege escalation flaw in udev
A vulnerability in udev, the user-space tool that manages the Linux /dev tree, has left unpatched systems vulnerable to a local root privilege escalation. Exploits are already circulating on the full-disclosure mailing list, so it is rather important for users and administrators to update their systems. The problem was caused by the way udev processes the messages it receives—certain kinds of messages, which could be generated by user processes, were not considered. That oversight led to the vulnerability.
The ever-expanding nature of the /dev tree, along with the rise of more dynamic hardware environments, led to the creation of udev in 2003. It replaced the devfs filesystem that was an earlier attempt to solve those problems. Unfortunately, devfs codified device naming policy into the kernel—something the kernel hackers try to avoid. By moving those decisions to user space with udev, that problem—along with a number of others—was resolved.
In order for udevd (the udev daemon) to do its job, it needs a way to be informed by the kernel when devices come and go—typically because the user attached or detached some device. A standard Linux way to send messages between the kernel and user space is via a netlink socket. Netlink sockets are an inter-process communication (IPC) mechanism that is geared for kernel to user space (and vice versa) IPC. It provides the well-understood sockets API to user space programs and is a much more flexible IPC mechanism than other possible choices.
One of the nice features of netlink sockets is the ability to multicast messages (i.e. a message sent to multiple recipients). Each netlink protocol type can have up to 32 multicast groups associated with it. Typically, multicast messages can only be sent and received by root, though some netlink protocol types will allow non-root processes to send and/or receive multicast messages. In fact, a recent change to the kernel allows non-root processes to receive—but not send—the udev multicast messages (which are also known as uevents).
Since only root processes can send the multicast uevents, it would seem there is no hole to exploit. Unfortunately, no one considered unicast messages. Any process can send a unicast netlink message to any other process, just by addressing it to a particular pid. It is up to the recipient to decide whether to accept and process the message. Because these unicast messages fell through the cracks, udevd would happily process them—creating devices as specified by a potentially malicious user. One of the more obvious exploits would be to create world-writeable block device corresponding to the root filesystem—other, nastier exploits are likely possible as well.
The fix was straightforward: enabling credentials (a header placed on each message by the kernel that includes the uid and pid of the sender) for the netlink socket, then requiring that all messages received have a uid of zero, which Kay Sievers added on April 8. Scott James Remnant added some additional checks shortly thereafter, requiring that messages received are not unicast and have been sent by the kernel.
Sievers says that either
patch "alone would be sufficient
" to fix the problem and that
doing both is, in
some sense, defensive programming. The credentials check is needed for
upcoming changes, he said, and Remnant's checks will take care of a
theoretical concern: "a confined
root process inside SELinux or AppArmor jail, which in fact is not
root in the usual sense, has no privileges, but could have the uid
0
". While Sievers didn't think the theory was particularly viable,
checking for a sender pid of zero (as Remnant's change does) will
take care of that problem as well.
This vulnerability illustrates a fairly common mistake: not considering all of the ways that input can reach a program. Every input mechanism factors into the "attack surface" of a program (or system). In this case, messages that—up until very recently at least—couldn't even be seen by non-root processes, could be sent by them. It is not uncommon for developers to focus on the "normal" usage of an input mechanism and miss a lesser, but still valid, use.
It is interesting to see that this vulnerability has a strange overlap with the capabilities flaw we reported on last week. In both cases, an exploit would use a device node created by mknod(), which is, itself, an uncommonly-used system call. These are the kinds of places that attackers are likely to focus their efforts. One hopes that other users of netlink sockets—routing daemons, netfilter, firewall applications, and others—have examined their code for similar problems.
Index entries for this article | |
---|---|
Kernel | Security/Vulnerabilities |
Security | Vulnerabilities/Privilege escalation |
Posted Apr 22, 2009 15:22 UTC (Wed)
by sladen (guest, #27402)
[Link]
Posted Apr 22, 2009 18:05 UTC (Wed)
by pheldens (guest, #19366)
[Link] (11 responses)
Posted Apr 22, 2009 18:25 UTC (Wed)
by tzafrir (subscriber, #11501)
[Link] (5 responses)
On a server system it should work.
Posted Apr 23, 2009 0:42 UTC (Thu)
by smithj (guest, #38034)
[Link] (4 responses)
Posted Apr 23, 2009 8:45 UTC (Thu)
by janfrode (subscriber, #244)
[Link] (3 responses)
Posted Apr 23, 2009 13:25 UTC (Thu)
by cesarb (subscriber, #6266)
[Link] (1 responses)
Posted Apr 23, 2009 16:07 UTC (Thu)
by janfrode (subscriber, #244)
[Link]
Posted Apr 24, 2009 18:43 UTC (Fri)
by smithj (guest, #38034)
[Link]
Your milage may vary.
Posted Apr 22, 2009 18:28 UTC (Wed)
by proski (subscriber, #104)
[Link] (4 responses)
Posted Apr 22, 2009 19:16 UTC (Wed)
by pranith (subscriber, #53092)
[Link] (2 responses)
Posted Apr 22, 2009 21:12 UTC (Wed)
by jengelh (guest, #33263)
[Link]
Posted Apr 22, 2009 21:46 UTC (Wed)
by arjan (subscriber, #36785)
[Link]
Posted Apr 23, 2009 7:03 UTC (Thu)
by jabby (guest, #2648)
[Link]
Posted Apr 22, 2009 22:29 UTC (Wed)
by Trou.fr (subscriber, #26289)
[Link]
So on udev > 116, you have arbitrary command execution as root, for any users, 100% reliable, not arch specific.
One of the most important vulnerabilities in years on GNU/Linux systems imho.
Posted Apr 22, 2009 22:40 UTC (Wed)
by nix (subscriber, #2304)
[Link] (7 responses)
This would have fixed the NFS problem, at least, although not the udev
(More evilly still, if you indicate this in the superblock and have it be
Posted Apr 23, 2009 0:05 UTC (Thu)
by jreiser (subscriber, #11027)
[Link]
Before there was kernel-level virtualization (vmware, xen, kvm, ...) there were partial virtualization environments which needed devices. If you have a machine with trusted users only and/or global protection, then mknod() can be handy for experiments.
Posted Apr 23, 2009 0:39 UTC (Thu)
by dlang (guest, #313)
[Link] (2 responses)
Posted Apr 23, 2009 15:24 UTC (Thu)
by Tet (guest, #5433)
[Link] (1 responses)
Posted Apr 24, 2009 10:37 UTC (Fri)
by nix (subscriber, #2304)
[Link]
(RAID-atop-LVM is not prone to this because you don't get the same excess
Posted Apr 23, 2009 11:52 UTC (Thu)
by etienne_lorrain@yahoo.fr (guest, #38022)
[Link] (1 responses)
How would you ask ioctl like BLKBSZGET, BLKSSZGET, BLKGETSIZE,
There is maybe a better solution (without having to guess the mount
Posted Apr 23, 2009 13:56 UTC (Thu)
by nix (subscriber, #2304)
[Link]
Posted Apr 23, 2009 13:52 UTC (Thu)
by Ross (guest, #4065)
[Link]
I believe that installers also create these files in /tmp if you want another example.
Posted Apr 23, 2009 7:09 UTC (Thu)
by jimparis (guest, #38647)
[Link] (2 responses)
It would be nice to at least hint at the fact that this fixes a critical security flaw... the release notes for udev 141 didn't even suggest that there was any reason to upgrade: http://lwn.net/Articles/328340/
That's pathetic.
Posted Apr 23, 2009 14:12 UTC (Thu)
by BenHutchings (subscriber, #37955)
[Link] (1 responses)
Posted Apr 23, 2009 17:08 UTC (Thu)
by jimparis (guest, #38647)
[Link]
Posted Apr 23, 2009 11:10 UTC (Thu)
by kaber (guest, #18366)
[Link]
- netlink supports 2^32-1 groups in recent kernel versions
- the proper way to check that a message is from the kernel is to check for a PID of zero. Its also worth noting that netlink PIDs are just numerical identifiers with a badly chosen name, they have no direct relationship to process PIDs.
- regarding other netlink users: the exactly same bug was present in iproute and IIRC the *swan keying daemons a couple of years ago. I'd expect it to be present in more software using netlink.
Netlink for userspace to userspace communication seems like a pretty useless feature, unfortunately we can't remove it or require receiving processes to optionally enable it for compatibility reasons.
Linux-Vserver container instances are a case where rootness checking
uid=0
is root, possibly CAP_NET_ADMIN
, but not CAP_SYS_ADMIN
.
A privilege escalation flaw in udev
A privilege escalation flaw in udev
A privilege escalation flaw in udev
The Red Hat errata for this fix says:
A privilege escalation flaw in udev
Before applying this update, make sure that all previously-released
errata relevant to your system have been applied.
Is that just the normal cop out, or are there any reasons to worry upgrading udev on a RHEL5u0 will break something.. ?
A privilege escalation flaw in udev
A privilege escalation flaw in udev
A privilege escalation flaw in udev
A privilege escalation flaw in udev
A privilege escalation flaw in udev
A privilege escalation flaw in udev
A privilege escalation flaw in udev
reboot?
A privilege escalation flaw in udev
A privilege escalation flaw in udev
nodes outside /dev? (Or, more generally, why isn't a special mount option
required to create device nodes on a filesystem? The ability to create
device nodes absolutely anywhere is a 'feature' of Unix that I've never
seen be of actual use to anyone except attackers.)
hole (as udev would have created the node in /dev, which would have had
that flag...)
set at mkfs time --- also not problematic for your average system with a
tmpfs /dev --- this lets us recycle the now-unused st_rdev field in the
inode for something else. Not a huge saving, true, but it *is* a saving,
and there are a *lot* of inodes on your average system.)
Can anyone think of a reason why mknod() allows *anyone* to create device
nodes outside /dev?
A privilege escalation flaw in udev
A privilege escalation flaw in udev
A privilege escalation flaw in udev
A privilege escalation flaw in udev
get it wrong you get a silent substantial slowdown...
RMW cycles.)
A privilege escalation flaw in udev
> to create device nodes outside /dev?
BLKGETSIZE64, HDIO_GETGEO_BIG, to the file system which contains
a file given as parameter?
As an example:
http://www.mirrorservice.org/sites/download.sourceforge.n...
point *name*) - I am listening...
A privilege escalation flaw in udev
A privilege escalation flaw in udev
under /mnt or wherever. The kernel shouldn't "know" that /dev is special.
A privilege escalation flaw in udev
"libudev: monitor - unify socket message handling"
No, that commit does what it says. The commit that fixed this bug was made by Scott James Remnant and has the subject "libudev: monitor - ignore messages from unusual sources". This is not entirely explicit, but it may not have immediately occurred to him that this was a severe security flaw. I can say that he was fairly quick to notify others about it.
A privilege escalation flaw in udev
That is not true. Go look at Kay's commit. It adds the SO_PASSCRED option to the socket and adds an explicit check for (cred->uid != 0). As the LWN writeup indicated, 'either patch "alone would be sufficient" to fix the problem'.
And your statement about him being quick to notify others is misleading at best. There has still not been a single posting on the udev mailing list about this problem!
A privilege escalation flaw in udev
A privilege escalation flaw in udev