Protecting /proc/slabinfo
User-space access to internal kernel information is always something of a balancing act. That information can be useful for debugging or diagnosing problems, but it can also be used by attackers to simplify exploiting security vulnerabilities. At first glance, protecting /proc/slabinfo so that it can't be read by non-root users seems like a reasonable restriction to help reduce targeted heap corruption exploits, but as a patch to do so was discussed, it became clear that there are some more subtle issues to consider.
Memory for kernel objects is managed by the "slab" allocator, which allocates those objects into separate slabs based on their size. The kernel has several different slab allocators available, and users (or distributions) can choose the one they want to use when configuring the kernel. The exploits discussed in the thread were mostly aimed at the SLUB allocator because it mixes multiple object types of the same size into slabs.
The output from /proc/slabinfo lists the various slabs in use, the size of objects that they contain, the number of objects currently used in the slab, and so on. That information can be used to manipulate the heap layout in a way that's favorable to attackers.
Dan Rosenberg proposed changing the permissions of /proc/slabinfo
to 0400, noting that "nearly all recent public exploits for heap
issues rely on feedback from /proc/slabinfo to manipulate heap layout
into an exploitable state
". As he points out, normal users
shouldn't really need access to that file, and on systems where that is
desirable, the administrator can set the permissions appropriately.
While few argued that unprivileged users need access to the information (at least by default), there were immediate questions about whether shutting off the access would really be an obstacle for attackers. Matt Mackall put it this way:
That "10x" factor is important. If it were several order of magnitudes higher, it would be clearer that possibly inconveniencing some users is worthwhile. But making an attacker only work ten times harder may not be worth it as Mackall observes:
Mackall describes the basic idea behind these "heap smashing" attacks well, but Rosenberg gives a more detailed description of how they work:
So an attacker that can observe /proc/slabinfo can gain a great deal of information about slabs that would allow them to arrange the situation they need on the heap. But in the discussion, it became clear that there are other ways to gain some of that information (via observing /proc/meminfo for instance), though it turns out that an attacker can rely on probability to arrange objects in the "right" order.
One could, as Mackall suggested, pre-allocate a large number of objects such that a new page is allocated to the slab. The contents of that page are then largely under the control of the attacker, so freeing one of those objects and allocating the other kind will very likely result in the needed arrangement.
That led Pekka Enberg to propose a patch that would randomize the object layout within a slab. The idea is that attackers couldn't depend on the current sequential allocation of objects in the slab, as the free list in a new slab would be in a random order. When freeing one object and then allocating another, there would be no guarantee that the two would be sequential. That approach, too, falls by the wayside because of probability.
Even with a randomized slab, an attacker can half fill the slab page with overrunnable objects, then allocate an exploitable object; it will then have a roughly 50% chance of being in the right place. One could also fill the slab page with overrunnable objects, then free an object—or every tenth object. The holes left behind will have a high probability being in the right place. Essentially, Mackall and others in the thread showed that the current attacks using /proc/slabinfo output were insufficiently imaginative.
Mackall noted that the real underlying problem is that it is too easy for programmers to copy the wrong amount of data from user space (which is how most of these object overruns occur). He suggested that a copy_from_user() interface that was harder to get wrong might help reduce these kinds of problems:
We need functions that are hard to abuse and coding patterns that are easy to copy, easy to review, and take the tricky bits out of the hands of driver writers.
There was general agreement that better interfaces should be added to reduce
these kinds of problems. Alan Cox mentioned
that Arjan van de Ven had created some "copy_from_user validation
code [that] already does verification checks
on the copies using gcc magic
". While Rosenberg is still interested
in pursuing the /proc/slabinfo protection along with Enberg's slab
randomization patch, it's not clear that there will be much support for it
from other kernel developers. Given that it imposes a performance penalty
along with potentially inconveniencing users, without any real benefit, it
may be rather hard to sell.
Index entries for this article | |
---|---|
Kernel | Security |
Security | Linux kernel |
Posted Mar 10, 2011 9:20 UTC (Thu)
by PaXTeam (guest, #24616)
[Link]
or more likely, exploit writers are not their own enemy and spend only as much time (and complexity) on their exploits as they can get away with...
Posted Mar 10, 2011 13:01 UTC (Thu)
by nix (subscriber, #2304)
[Link]
Posted Mar 10, 2011 17:54 UTC (Thu)
by rilder (guest, #59804)
[Link] (2 responses)
Posted Mar 10, 2011 20:06 UTC (Thu)
by nevets (subscriber, #11875)
[Link]
"When all you have is a hammer, everything looks like a nail.".
Not saying it's a bad idea. I'm just saying it reminds me of that saying.
Posted Mar 15, 2011 22:47 UTC (Tue)
by steffen780 (guest, #68142)
[Link]
Posted Mar 18, 2011 4:19 UTC (Fri)
by kevinm (guest, #69913)
[Link]
That will immediately advantage even people running older kernels, and the distros are in the best place to shake out (and fix) any userspace breakage.
Protecting /proc/slabinfo
> attacks using /proc/slabinfo output were insufficiently imaginative.
Protecting /proc/slabinfo
Protecting /proc/slabinfo
Protecting /proc/slabinfo
Protecting /proc/slabinfo
Protecting /proc/slabinfo