2011-03-03 17:51:04

by Dan Rosenberg

[permalink] [raw]
Subject: [PATCH] Make /proc/slabinfo 0400

Allowing unprivileged users to read /proc/slabinfo represents a security
risk, since revealing details of slab allocations can expose information
that is useful when exploiting kernel heap corruption issues. This is
evidenced by observing that nearly all recent public exploits for heap
issues rely on feedback from /proc/slabinfo to manipulate heap layout
into an exploitable state.

Changing the permissions on this file to 0400 by default will make heap
corruption issues more difficult to exploit. Ordinary usage should not
require unprivileged users to debug the running kernel; if this ability
is required, an admin can always chmod the file appropriately.


Signed-off-by: Dan Rosenberg <[email protected]>
---
mm/slab.c | 3 ++-
mm/slub.c | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/mm/slab.c b/mm/slab.c
index 37961d1..7f719f6 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -4535,7 +4535,8 @@ static const struct file_operations proc_slabstats_operations = {

static int __init slab_proc_init(void)
{
- proc_create("slabinfo",S_IWUSR|S_IRUGO,NULL,&proc_slabinfo_operations);
+ proc_create("slabinfo", S_IWUSR|S_IRUSR, NULL,
+ &proc_slabinfo_operations);
#ifdef CONFIG_DEBUG_SLAB_LEAK
proc_create("slab_allocators", 0, NULL, &proc_slabstats_operations);
#endif
diff --git a/mm/slub.c b/mm/slub.c
index e15aa7f..5f57834 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -4691,7 +4691,7 @@ static const struct file_operations proc_slabinfo_operations = {

static int __init slab_proc_init(void)
{
- proc_create("slabinfo", S_IRUGO, NULL, &proc_slabinfo_operations);
+ proc_create("slabinfo", S_IRUSR, NULL, &proc_slabinfo_operations);
return 0;
}
module_init(slab_proc_init);


2011-03-03 18:17:50

by Dave Hansen

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Thu, 2011-03-03 at 12:50 -0500, Dan Rosenberg wrote:
> --- a/mm/slub.c
> +++ b/mm/slub.c
> @@ -4691,7 +4691,7 @@ static const struct file_operations proc_slabinfo_operations = {
>
> static int __init slab_proc_init(void)
> {
> - proc_create("slabinfo", S_IRUGO, NULL, &proc_slabinfo_operations);
> + proc_create("slabinfo", S_IRUSR, NULL, &proc_slabinfo_operations);
> return 0;
> }
> module_init(slab_proc_init);

Please don't. In reality, it'll just mean that more data collection
things will have to get done as root, and I'll wear my keyboard out more
often sudo'ing.

If you really want this on particularly pedantic systems, why not chmod?

-- Dave

2011-03-03 18:30:03

by Dan Rosenberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400


>
> Please don't. In reality, it'll just mean that more data collection
> things will have to get done as root, and I'll wear my keyboard out more
> often sudo'ing.
>
> If you really want this on particularly pedantic systems, why not chmod?
>

I believe the vast majority of users do not need the ability to read
this file from an unprivileged login. We should strive for security by
default. As you said, you can simply chmod this file to regain the
access permissions you require for your less common use case.

> -- Dave

2011-03-03 20:58:11

by Matt Mackall

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Thu, 2011-03-03 at 12:50 -0500, Dan Rosenberg wrote:
> Allowing unprivileged users to read /proc/slabinfo represents a security
> risk, since revealing details of slab allocations can expose information
> that is useful when exploiting kernel heap corruption issues. This is
> evidenced by observing that nearly all recent public exploits for heap
> issues rely on feedback from /proc/slabinfo to manipulate heap layout
> into an exploitable state.

Looking at a couple of these exploits, my suspicion is that looking at
slabinfo simply improves the odds of success by a small factor (ie 10x
or so) and doesn't present a real obstacle to attackers. All that
appears to be required is to arrange that an overrunnable object be
allocated next to one that is exploitable when overrun. And that can be
arranged with fairly high probability on SLUB's merged caches.

On the other hand, I'm not convinced the contents of this file are of
much use to people without admin access.

--
Mathematics is the supreme nostalgia of our time.

2011-03-03 21:16:33

by Dan Rosenberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400


>
> Looking at a couple of these exploits, my suspicion is that looking at
> slabinfo simply improves the odds of success by a small factor (ie 10x
> or so) and doesn't present a real obstacle to attackers. All that
> appears to be required is to arrange that an overrunnable object be
> allocated next to one that is exploitable when overrun. And that can be
> arranged with fairly high probability on SLUB's merged caches.
>

This is accurate, but the primary goal of exploit mitigation isn't
necessarily to completely prevent the possibility of exploitation (time
has shown that this is unlikely to be feasible), but rather to increase
the cost of investment required to develop a reliable exploit. If
removing read access to /proc/slabinfo means that heap exploits are even
slightly more likely to fail, then that's a win as far as I'm concerned
and may be the thing that prevents some helpless end user from getting
compromised.

> On the other hand, I'm not convinced the contents of this file are of
> much use to people without admin access.
>

Exactly. We might as well do everything we can to make attackers' lives
more difficult, especially when the cost is so low.

-Dan

> --
> Mathematics is the supreme nostalgia of our time.

2011-03-03 21:44:31

by Matt Mackall

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Thu, 2011-03-03 at 16:16 -0500, Dan Rosenberg wrote:
> >
> > Looking at a couple of these exploits, my suspicion is that looking at
> > slabinfo simply improves the odds of success by a small factor (ie 10x
> > or so) and doesn't present a real obstacle to attackers. All that
> > appears to be required is to arrange that an overrunnable object be
> > allocated next to one that is exploitable when overrun. And that can be
> > arranged with fairly high probability on SLUB's merged caches.
> >
>
> This is accurate, but the primary goal of exploit mitigation isn't
> necessarily to completely prevent the possibility of exploitation (time
> has shown that this is unlikely to be feasible), but rather to increase
> the cost of investment required to develop a reliable exploit. If
> removing read access to /proc/slabinfo means that heap exploits are even
> slightly more likely to fail, then that's a win as far as I'm concerned
> and may be the thing that prevents some helpless end user from getting
> compromised.

Well if it were a 1000x-1000000x difficulty improvement, I would say you
had a point. But at 10x, it's just not a real obstacle. For instance, in
this exploit:

http://www.exploit-db.com/exploits/14814/

..there's already detection of successful smashing, so working around
not having /proc/slabinfo is as simple as putting the initial smash in a
loop. I can probably improve my odds of success to nearly 100% by
pre-allocating a ton of objects all at once to get my own private slab
page and tidy adjoining allocations. I'll only fail if someone does a
simultaneous allocation between my target objects or I happen to
straddle slab pages.

And once an exploit writer has figured that out once, everyone else just
copies it (like they've copied the slabinfo technique). At which point,
we might as well make the file more permissive again..

> > On the other hand, I'm not convinced the contents of this file are of
> > much use to people without admin access.
> >
>
> Exactly. We might as well do everything we can to make attackers' lives
> more difficult, especially when the cost is so low.

There are thousands of attackers and millions of users. Most of those
millions are on single-user systems with no local attackers. For every
attacker's life we make trivially more difficult, we're also making a
few real user's lives more difficult. It's not obvious that this is a
good trade-off.

--
Mathematics is the supreme nostalgia of our time.

2011-03-03 22:30:08

by Dan Rosenberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400


> Well if it were a 1000x-1000000x difficulty improvement, I would say you
> had a point. But at 10x, it's just not a real obstacle. For instance, in
> this exploit:
>
> http://www.exploit-db.com/exploits/14814/
>
> ..there's already detection of successful smashing, so working around
> not having /proc/slabinfo is as simple as putting the initial smash in a
> loop. I can probably improve my odds of success to nearly 100% by
> pre-allocating a ton of objects all at once to get my own private slab
> page and tidy adjoining allocations. I'll only fail if someone does a
> simultaneous allocation between my target objects or I happen to
> straddle slab pages.
>

For this particular exploit, the allocation and triggering of the
vulnerability were in separate stages, so that's the case, but other
exploits might have additional constraints. For example, there is a
public exploit for a two-byte SLUB overflow that relies on a partial
overwrite into a free chunk; exploitation of vulnerabilities similar to
this may be significantly hindered by the lack of availability of this
interface. Still other issues may only get one shot at exploitation
without needing to clean up corrupted heap state to avoid panicking the
kernel. In short, every exploit is different, and exposure
of /proc/slabinfo may be the thing that puts some more difficult cases
within reach.

> And once an exploit writer has figured that out once, everyone else just
> copies it (like they've copied the slabinfo technique). At which point,
> we might as well make the file more permissive again..
>

This may be true to some extent, but kernel vulnerabilities tend to be
somewhat varied in terms of exploitation constraints, so I'm not
convinced a general technique would apply to enough cases to render this
change completely pointless.

Many security features, for example NX enforcement, have not proven to
be especially significant in completely mitigating exploitation of
userland memory corruption vulnerabilities by themselves, given the
advent of code-reuse exploitation techniques. They have also come at
the cost of breaking some applications. However, the reason we don't
just turn them all off is because they provide SOME hurdle, however
small, and given enough incremental improvements, we eventually get to
the point where things are actually hard.

> > > On the other hand, I'm not convinced the contents of this file are of
> > > much use to people without admin access.
> > >
> >
> > Exactly. We might as well do everything we can to make attackers' lives
> > more difficult, especially when the cost is so low.
>
> There are thousands of attackers and millions of users. Most of those
> millions are on single-user systems with no local attackers. For every
> attacker's life we make trivially more difficult, we're also making a
> few real user's lives more difficult. It's not obvious that this is a
> good trade-off.
>

I appreciate your input on this, you've made very reasonable points.
I'm just not convinced that those few real users are being substantially
inconvenienced, even if there's only a small benefit for the larger
population of users who are at risk for attacks. Perhaps others could
contribute their opinions to the discussion.

-Dan

> --
> Mathematics is the supreme nostalgia of our time.

2011-03-03 23:08:24

by Matt Mackall

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Thu, 2011-03-03 at 17:30 -0500, Dan Rosenberg wrote:
> > Well if it were a 1000x-1000000x difficulty improvement, I would say you
> > had a point. But at 10x, it's just not a real obstacle. For instance, in
> > this exploit:
> >
> > http://www.exploit-db.com/exploits/14814/
> >
> > ..there's already detection of successful smashing, so working around
> > not having /proc/slabinfo is as simple as putting the initial smash in a
> > loop. I can probably improve my odds of success to nearly 100% by
> > pre-allocating a ton of objects all at once to get my own private slab
> > page and tidy adjoining allocations. I'll only fail if someone does a
> > simultaneous allocation between my target objects or I happen to
> > straddle slab pages.
> >
>
> For this particular exploit, the allocation and triggering of the
> vulnerability were in separate stages, so that's the case, but other
> exploits might have additional constraints. For example, there is a
> public exploit for a two-byte SLUB overflow that relies on a partial
> overwrite into a free chunk; exploitation of vulnerabilities similar to
> this may be significantly hindered by the lack of availability of this
> interface. Still other issues may only get one shot at exploitation
> without needing to clean up corrupted heap state to avoid panicking the
> kernel. In short, every exploit is different, and exposure
> of /proc/slabinfo may be the thing that puts some more difficult cases
> within reach.
>
> > And once an exploit writer has figured that out once, everyone else just
> > copies it (like they've copied the slabinfo technique). At which point,
> > we might as well make the file more permissive again..
> >
>
> This may be true to some extent, but kernel vulnerabilities tend to be
> somewhat varied in terms of exploitation constraints, so I'm not
> convinced a general technique would apply to enough cases to render this
> change completely pointless.
>
> Many security features, for example NX enforcement, have not proven to
> be especially significant in completely mitigating exploitation of
> userland memory corruption vulnerabilities by themselves, given the
> advent of code-reuse exploitation techniques. They have also come at
> the cost of breaking some applications. However, the reason we don't
> just turn them all off is because they provide SOME hurdle, however
> small, and given enough incremental improvements, we eventually get to
> the point where things are actually hard.
>
> > > > On the other hand, I'm not convinced the contents of this file are of
> > > > much use to people without admin access.
> > > >
> > >
> > > Exactly. We might as well do everything we can to make attackers' lives
> > > more difficult, especially when the cost is so low.
> >
> > There are thousands of attackers and millions of users. Most of those
> > millions are on single-user systems with no local attackers. For every
> > attacker's life we make trivially more difficult, we're also making a
> > few real user's lives more difficult. It's not obvious that this is a
> > good trade-off.
> >
>
> I appreciate your input on this, you've made very reasonable points.
> I'm just not convinced that those few real users are being substantially
> inconvenienced, even if there's only a small benefit for the larger
> population of users who are at risk for attacks. Perhaps others could
> contribute their opinions to the discussion.

That's my hope, as I'm basically on the fence.

--
Mathematics is the supreme nostalgia of our time.

2011-03-04 00:32:55

by Dave Hansen

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Thu, 2011-03-03 at 17:08 -0600, Matt Mackall wrote:
> > I appreciate your input on this, you've made very reasonable points.
> > I'm just not convinced that those few real users are being substantially
> > inconvenienced, even if there's only a small benefit for the larger
> > population of users who are at risk for attacks. Perhaps others could
> > contribute their opinions to the discussion.


Kees Cook was nice enough to point out a few of the ways this can get
misused. It looks like the basic pattern is to use slabinfo to
determine where an object was likely to have been allocated in the slab
in order to more precisely target the next stage of the attack.

I do see how much easier slabinfo makes this. Do any of the attacks
that we know about rely on anything _but_ trying to figure out when a
slab page got consumed?

If I were an attacker, I'd probably just start watching /proc/meminfo
for when Slab/SReclaimable/SUnreclaim get bumped. That'll also give me
a pretty good indicator of where my object is in the slab.

Granted, doing that still puts one more level of opaqueness in the way.
slabinfo definitely makes it more straightforward.

-- Dave

2011-03-04 00:59:56

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400


On Mar 3, 2011, at 5:30 PM, Dan Rosenberg wrote:

> I appreciate your input on this, you've made very reasonable points.
> I'm just not convinced that those few real users are being substantially
> inconvenienced, even if there's only a small benefit for the larger
> population of users who are at risk for attacks. Perhaps others could
> contribute their opinions to the discussion.

Being able to monitor /proc/slabinfo is incredibly useful for finding various
kernel problems. We can see if some part of the kernel is out of balance,
and we can also find memory leaks. I once saved a school system's Linux
deployment because their systems were crashing once a week, and becoming
progressively more unreliable before they crashed, and the school board
was about to pull the plug.

Turned out the "virus scanner" was a piece of garbage that slowly leaked
memory over time, and since it was proprietary code that was loaded as
a kernel module, it showed up in /proc/slabinfo. If it had been protected
it would have been much harder for me to get access to such debugging
data.

I wonder if there is some other change we could make to the slab allocator
that would make it harder for exploit writers without having to protect the
/proc/slabinfo file. For example, could we randomly select different free
objects in a page instead of filling them in sequentially?

-- Ted

2011-03-04 06:52:08

by Pekka Enberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Mar 3, 2011, at 5:30 PM, Dan Rosenberg wrote:
>> I appreciate your input on this, you've made very reasonable points.
>> I'm just not convinced that those few real users are being substantially
>> inconvenienced, even if there's only a small benefit for the larger
>> population of users who are at risk for attacks. ?Perhaps others could
>> contribute their opinions to the discussion.

On Fri, Mar 4, 2011 at 2:50 AM, Theodore Tso <[email protected]> wrote:
> Being able to monitor /proc/slabinfo is incredibly useful for finding various
> kernel problems. ?We can see if some part of the kernel is out of balance,
> and we can also find memory leaks. ? I once saved a school system's Linux
> deployment because their systems were crashing once a week, and becoming
> progressively more unreliable before they crashed, and the school board
> was about to pull the plug.

Indeed. However, I'm not sure we need to expose the number of _active
objects_ to non-CAP_ADMIN users (which could be set to zeros if you
don't have sufficient privileges). Memory leaks can be detected from
the total number of objects anyway, no?

On Fri, Mar 4, 2011 at 2:50 AM, Theodore Tso <[email protected]> wrote:
> I wonder if there is some other change we could make to the slab allocator
> that would make it harder for exploit writers without having to protect the
> /proc/slabinfo file. ?For example, could we randomly select different free
> objects in a page instead of filling them in sequentially?

We can do something like that if we can live with the performance costs.

2011-03-04 11:58:48

by Alan

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

> Being able to monitor /proc/slabinfo is incredibly useful for finding various
> kernel problems. We can see if some part of the kernel is out of balance,

Making it 0400 doesn't stop that.

Alan

2011-03-04 17:36:20

by Dave Hansen

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, 2011-03-04 at 08:52 +0200, Pekka Enberg wrote:
> On Fri, Mar 4, 2011 at 2:50 AM, Theodore Tso <[email protected]> wrote:
> > Being able to monitor /proc/slabinfo is incredibly useful for finding various
> > kernel problems. We can see if some part of the kernel is out of balance,
> > and we can also find memory leaks. I once saved a school system's Linux
> > deployment because their systems were crashing once a week, and becoming
> > progressively more unreliable before they crashed, and the school board
> > was about to pull the plug.
>
> Indeed. However, I'm not sure we need to expose the number of _active
> objects_ to non-CAP_ADMIN users (which could be set to zeros if you
> don't have sufficient privileges). Memory leaks can be detected from
> the total number of objects anyway, no?

This:

http://www.exploit-db.com/exploits/14814/

loops doing allocations until total==active, and then does one more
allocation to get the position in the slab it needs. If we mask
'active', it'll just loop until 'total' gets bumped, and then consider
the _previous_ allocation to have been the one that was in the necessary
position.

As Ted mentioned, the real issue here is being able to infer location
inside the slab by correlating your allocations with when the slab
statistics get bumped. You can do that with slabinfo pretty precisely,
but you can probably also pull it off with meminfo too, albeit with less
precision.

We need to either keep the bad guys away from the counts (this patch),
or de-correlate the counts moving around with the position of objects in
the slab. Ted's suggestion is a good one, and the only other thing I
can think of is to make the values useless, perhaps by batching and
delaying the (exposed) counts by a random amount.

-- Dave

2011-03-04 17:49:44

by Linus Torvalds

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, Mar 4, 2011 at 9:36 AM, Dave Hansen <[email protected]> wrote:
>
> We need to either keep the bad guys away from the counts (this patch),
> or de-correlate the counts moving around with the position of objects in
> the slab. ?Ted's suggestion is a good one, and the only other thing I
> can think of is to make the values useless, perhaps by batching and
> delaying the (exposed) counts by a random amount.

We might just decide to expose the 'active' count for regular users
(and then, in case there are tools there that parse this as normal
users, we could set the 'total' fields to be the same as the active
one, possibly rounded up to the slab allocation or something.

I know, I know, from a memory usage standpoint, 'active' is secondary,
but it still correlates fairly well, so it's still useful. And for
seeing memory leaks (as opposed to slab fragmentation etc issues),
it's actually the interesting case.

And at the same time, it's actually much less involved with actual
physical allocations than 'total' is, and thus much less of an attack
vector. The fact that we got another socket allocation when we opened
a new socket is not "useful" information for an attacker, not in the
way it is to see a hint of _where_ the socket got allocated.

Of course, as you say, '/proc/meminfo' still does give you the trigger
for "oh, now somebody actually allocated a new page". That's totally
independent of slabinfo, though (and knowing the number of active
slabs would neither help nor hurt somebody who uses meminfo - you
might as well allocate new sockets in a loop, and use _only_ meminfo
to see when that allocated a new page).

Linus

2011-03-04 18:15:00

by Matt Mackall

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, 2011-03-04 at 09:48 -0800, Linus Torvalds wrote:
> On Fri, Mar 4, 2011 at 9:36 AM, Dave Hansen <[email protected]> wrote:
> >
> > We need to either keep the bad guys away from the counts (this patch),
> > or de-correlate the counts moving around with the position of objects in
> > the slab. Ted's suggestion is a good one, and the only other thing I
> > can think of is to make the values useless, perhaps by batching and
> > delaying the (exposed) counts by a random amount.
>
> We might just decide to expose the 'active' count for regular users
> (and then, in case there are tools there that parse this as normal
> users, we could set the 'total' fields to be the same as the active
> one, possibly rounded up to the slab allocation or something.
>
> I know, I know, from a memory usage standpoint, 'active' is secondary,
> but it still correlates fairly well, so it's still useful. And for
> seeing memory leaks (as opposed to slab fragmentation etc issues),
> it's actually the interesting case.
>
> And at the same time, it's actually much less involved with actual
> physical allocations than 'total' is, and thus much less of an attack
> vector. The fact that we got another socket allocation when we opened
> a new socket is not "useful" information for an attacker, not in the
> way it is to see a hint of _where_ the socket got allocated.
>
> Of course, as you say, '/proc/meminfo' still does give you the trigger
> for "oh, now somebody actually allocated a new page". That's totally
> independent of slabinfo, though (and knowing the number of active
> slabs would neither help nor hurt somebody who uses meminfo - you
> might as well allocate new sockets in a loop, and use _only_ meminfo
> to see when that allocated a new page).

I think lying to the user is much worse than changing the permissions.
The cost of the resulting confusion is WAY higher.

--
Mathematics is the supreme nostalgia of our time.

2011-03-04 20:02:53

by Pekka Enberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, Mar 4, 2011 at 8:14 PM, Matt Mackall <[email protected]> wrote:
>> Of course, as you say, '/proc/meminfo' still does give you the trigger
>> for "oh, now somebody actually allocated a new page". That's totally
>> independent of slabinfo, though (and knowing the number of active
>> slabs would neither help nor hurt somebody who uses meminfo - you
>> might as well allocate new sockets in a loop, and use _only_ meminfo
>> to see when that allocated a new page).
>
> I think lying to the user is much worse than changing the permissions.
> The cost of the resulting confusion is WAY higher.

Yeah, maybe. I've attached a proof of concept patch that attempts to
randomize object layout in individual slabs. I'm don't completely
understand the attack vector so I don't make any claims if the patch
helps or not.

Pekka


Attachments:
slub-randomize.patch (2.26 kB)

2011-03-04 20:31:58

by Matt Mackall

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, 2011-03-04 at 22:02 +0200, Pekka Enberg wrote:
> On Fri, Mar 4, 2011 at 8:14 PM, Matt Mackall <[email protected]> wrote:
> >> Of course, as you say, '/proc/meminfo' still does give you the trigger
> >> for "oh, now somebody actually allocated a new page". That's totally
> >> independent of slabinfo, though (and knowing the number of active
> >> slabs would neither help nor hurt somebody who uses meminfo - you
> >> might as well allocate new sockets in a loop, and use _only_ meminfo
> >> to see when that allocated a new page).
> >
> > I think lying to the user is much worse than changing the permissions.
> > The cost of the resulting confusion is WAY higher.
>
> Yeah, maybe. I've attached a proof of concept patch that attempts to
> randomize object layout in individual slabs. I'm don't completely
> understand the attack vector so I don't make any claims if the patch
> helps or not.

In general, the attack relies on getting an object A (vulnerable to
overrun) immediately beneath an object B (that can be exploited when
overrun).

I'm not sure how much randomization helps, though. Allocate 1000 objects
of type B, deallocate the 800th, then allocate an object of type A. It's
almost certainly next to a B.

--
Mathematics is the supreme nostalgia of our time.

2011-03-04 20:37:26

by Dan Rosenberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, 2011-03-04 at 22:02 +0200, Pekka Enberg wrote:
> On Fri, Mar 4, 2011 at 8:14 PM, Matt Mackall <[email protected]> wrote:
> >> Of course, as you say, '/proc/meminfo' still does give you the trigger
> >> for "oh, now somebody actually allocated a new page". That's totally
> >> independent of slabinfo, though (and knowing the number of active
> >> slabs would neither help nor hurt somebody who uses meminfo - you
> >> might as well allocate new sockets in a loop, and use _only_ meminfo
> >> to see when that allocated a new page).
> >
> > I think lying to the user is much worse than changing the permissions.
> > The cost of the resulting confusion is WAY higher.
>
> Yeah, maybe. I've attached a proof of concept patch that attempts to
> randomize object layout in individual slabs. I'm don't completely
> understand the attack vector so I don't make any claims if the patch
> helps or not.
>
> Pekka

Thanks for your work on this. The most general exploitation techniques
involving kernel SLUB/SLAB corruption involve manipulating heap state
such that an object that can be overflowed by the attacker resides
immediately before another object whose contents are worth overwriting,
or overflowing into the page following the slab. The most common known
techniques involve overflowing into an allocated object with useful
contents such as a function pointer and then triggering these (various
IPC-related structs are often used for this). It's also possible to
overflow into a free object and overwrite its free pointer, causing
subsequent allocations to result in a fake heap object residing in
userland being under an attacker's control.

This patch makes these techniques more difficult by making it hard to
know whether the last attacker-allocated object resides before a free or
allocated object. Especially with vulnerabilities that only allow one
attempt at exploitation before recovery is needed to avoid trashing too
much heap state and causing a crash, this could go a long way. I'd
still argue in favor of removing the ability to know how many objects
are used in a given slab, since randomizing objects doesn't help if you
know every object is allocated.

Of course people more knowledgeable on SLUB should look this over for
sanity's sake, but it looks good to me.

-Dan

2011-03-04 20:43:03

by Dan Rosenberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, 2011-03-04 at 14:31 -0600, Matt Mackall wrote:
> On Fri, 2011-03-04 at 22:02 +0200, Pekka Enberg wrote:
> > On Fri, Mar 4, 2011 at 8:14 PM, Matt Mackall <[email protected]> wrote:
> > >> Of course, as you say, '/proc/meminfo' still does give you the trigger
> > >> for "oh, now somebody actually allocated a new page". That's totally
> > >> independent of slabinfo, though (and knowing the number of active
> > >> slabs would neither help nor hurt somebody who uses meminfo - you
> > >> might as well allocate new sockets in a loop, and use _only_ meminfo
> > >> to see when that allocated a new page).
> > >
> > > I think lying to the user is much worse than changing the permissions.
> > > The cost of the resulting confusion is WAY higher.
> >
> > Yeah, maybe. I've attached a proof of concept patch that attempts to
> > randomize object layout in individual slabs. I'm don't completely
> > understand the attack vector so I don't make any claims if the patch
> > helps or not.
>
> In general, the attack relies on getting an object A (vulnerable to
> overrun) immediately beneath an object B (that can be exploited when
> overrun).
>
> I'm not sure how much randomization helps, though. Allocate 1000 objects
> of type B, deallocate the 800th, then allocate an object of type A. It's
> almost certainly next to a B.
>

On second thought, this does pose a problem. Even if you don't know how
full the most recent slab is or where free vs. used chunks are within
it, if you can guarantee that you filled an entire previous slab with
your objects and then free and reallocate one of them, then you can
still win.

-Dan

> --
> Mathematics is the supreme nostalgia of our time.

2011-03-04 20:56:17

by Pekka Enberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, 2011-03-04 at 14:31 -0600, Matt Mackall wrote:
>> On Fri, 2011-03-04 at 22:02 +0200, Pekka Enberg wrote:
>> > On Fri, Mar 4, 2011 at 8:14 PM, Matt Mackall <[email protected]> wrote:
>> > >> Of course, as you say, '/proc/meminfo' still does give you the trigger
>> > >> for "oh, now somebody actually allocated a new page". That's totally
>> > >> independent of slabinfo, though (and knowing the number of active
>> > >> slabs would neither help nor hurt somebody who uses meminfo - you
>> > >> might as well allocate new sockets in a loop, and use _only_ meminfo
>> > >> to see when that allocated a new page).
>> > >
>> > > I think lying to the user is much worse than changing the permissions.
>> > > The cost of the resulting confusion is WAY higher.
>> >
>> > Yeah, maybe. I've attached a proof of concept patch that attempts to
>> > randomize object layout in individual slabs. I'm don't completely
>> > understand the attack vector so I don't make any claims if the patch
>> > helps or not.
>>
>> In general, the attack relies on getting an object A (vulnerable to
>> overrun) immediately beneath an object B (that can be exploited when
>> overrun).
>>
>> I'm not sure how much randomization helps, though. Allocate 1000 objects
>> of type B, deallocate the 800th, then allocate an object of type A. It's
>> almost certainly next to a B.

On Fri, Mar 4, 2011 at 10:42 PM, Dan Rosenberg <[email protected]> wrote:
> On second thought, this does pose a problem. ?Even if you don't know how
> full the most recent slab is or where free vs. used chunks are within
> it, if you can guarantee that you filled an entire previous slab with
> your objects and then free and reallocate one of them, then you can
> still win.

Guys, I still don't get it, sorry.

Why can you still win? With my patch, reallocation shouldn't matter;
the freelist randomization ought to make it less likely for *any* two
allocated objects to be adjacent.

Pekka

2011-03-04 20:58:29

by Pekka Enberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, Mar 4, 2011 at 10:37 PM, Dan Rosenberg <[email protected]> wrote:
> This patch makes these techniques more difficult by making it hard to
> know whether the last attacker-allocated object resides before a free or
> allocated object. ?Especially with vulnerabilities that only allow one
> attempt at exploitation before recovery is needed to avoid trashing too
> much heap state and causing a crash, this could go a long way. ?I'd
> still argue in favor of removing the ability to know how many objects
> are used in a given slab, since randomizing objects doesn't help if you
> know every object is allocated.

So if the attacker knows every object is allocated, how does that help
if we're randomizing the initial freelist?

2011-03-04 21:08:36

by Dan Rosenberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, 2011-03-04 at 22:56 +0200, Pekka Enberg wrote:
> On Fri, 2011-03-04 at 14:31 -0600, Matt Mackall wrote:
> >> On Fri, 2011-03-04 at 22:02 +0200, Pekka Enberg wrote:
> >> > On Fri, Mar 4, 2011 at 8:14 PM, Matt Mackall <[email protected]> wrote:
> >> > >> Of course, as you say, '/proc/meminfo' still does give you the trigger
> >> > >> for "oh, now somebody actually allocated a new page". That's totally
> >> > >> independent of slabinfo, though (and knowing the number of active
> >> > >> slabs would neither help nor hurt somebody who uses meminfo - you
> >> > >> might as well allocate new sockets in a loop, and use _only_ meminfo
> >> > >> to see when that allocated a new page).
> >> > >
> >> > > I think lying to the user is much worse than changing the permissions.
> >> > > The cost of the resulting confusion is WAY higher.
> >> >
> >> > Yeah, maybe. I've attached a proof of concept patch that attempts to
> >> > randomize object layout in individual slabs. I'm don't completely
> >> > understand the attack vector so I don't make any claims if the patch
> >> > helps or not.
> >>
> >> In general, the attack relies on getting an object A (vulnerable to
> >> overrun) immediately beneath an object B (that can be exploited when
> >> overrun).
> >>
> >> I'm not sure how much randomization helps, though. Allocate 1000 objects
> >> of type B, deallocate the 800th, then allocate an object of type A. It's
> >> almost certainly next to a B.
>
> On Fri, Mar 4, 2011 at 10:42 PM, Dan Rosenberg <[email protected]> wrote:
> > On second thought, this does pose a problem. Even if you don't know how
> > full the most recent slab is or where free vs. used chunks are within
> > it, if you can guarantee that you filled an entire previous slab with
> > your objects and then free and reallocate one of them, then you can
> > still win.
>
> Guys, I still don't get it, sorry.
>
> Why can you still win? With my patch, reallocation shouldn't matter;
> the freelist randomization ought to make it less likely for *any* two
> allocated objects to be adjacent.
>

I could be mistaken on this, so feel free to correct me. What if you
just fill more than one slab with the object you'd like to overflow
into, then pick an object that's guaranteed to reside in a slab filled
with your objects. Upon freeing that object and allocating a new
to-be-overflowed object (that's sized so it's handled by the same slab
cache), this new object will be guaranteed to be sitting immediately
before one of your objects (or before the end of the slab if you're
unlucky). You can still win because it doesn't matter which specific
object you overflow, only that you overflow one of them.

-Dan

2011-03-04 21:10:42

by Dan Rosenberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, 2011-03-04 at 22:58 +0200, Pekka Enberg wrote:
> On Fri, Mar 4, 2011 at 10:37 PM, Dan Rosenberg <[email protected]> wrote:
> > This patch makes these techniques more difficult by making it hard to
> > know whether the last attacker-allocated object resides before a free or
> > allocated object. Especially with vulnerabilities that only allow one
> > attempt at exploitation before recovery is needed to avoid trashing too
> > much heap state and causing a crash, this could go a long way. I'd
> > still argue in favor of removing the ability to know how many objects
> > are used in a given slab, since randomizing objects doesn't help if you
> > know every object is allocated.
>
> So if the attacker knows every object is allocated, how does that help
> if we're randomizing the initial freelist?

If you know you've got a slab completely full of your objects, then it
doesn't matter that they happened to be allocated in a random fashion -
they're still all allocated, and by freeing one of them and
reallocating, you'll still be next to your target.

2011-03-04 21:13:00

by Matt Mackall

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, 2011-03-04 at 22:58 +0200, Pekka Enberg wrote:
> On Fri, Mar 4, 2011 at 10:37 PM, Dan Rosenberg <[email protected]> wrote:
> > This patch makes these techniques more difficult by making it hard to
> > know whether the last attacker-allocated object resides before a free or
> > allocated object. Especially with vulnerabilities that only allow one
> > attempt at exploitation before recovery is needed to avoid trashing too
> > much heap state and causing a crash, this could go a long way. I'd
> > still argue in favor of removing the ability to know how many objects
> > are used in a given slab, since randomizing objects doesn't help if you
> > know every object is allocated.
>
> So if the attacker knows every object is allocated, how does that help
> if we're randomizing the initial freelist?

First note that all of these attacks are probabilistic.

Now, with a randomized free list, if I create 1000 objects of type B,
then, on average, the partially-filled page the next allocation comes
from will be half-full of B objects. Thus, the next object will have a
50% chance of being in the right spot for an exploit.

Now if I delete the 800th B object, it's probably on a slab that's
otherwise full of B objects since we fill partial slabs before creating
new ones. If my next allocation comes from that slab, it will thus get a
spot that's almost guaranteed to be in the right spot.

Similarly, if I create 1000 objects and then delete every tenth one,
I've now got a swiss cheese heap where just about every hole is
well-positioned.

--
Mathematics is the supreme nostalgia of our time.

2011-03-04 21:30:59

by Pekka Enberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

Hi Dan,

[ Thanks to you and Matt for taking the time to explain this to me. ]

On Fri, Mar 4, 2011 at 11:08 PM, Dan Rosenberg <[email protected]> wrote:
> I could be mistaken on this, so feel free to correct me. ?What if you
> just fill more than one slab with the object you'd like to overflow
> into, then pick an object that's guaranteed to reside in a slab filled
> with your objects. ?Upon freeing that object and allocating a new
> to-be-overflowed object (that's sized so it's handled by the same slab
> cache), this new object will be guaranteed to be sitting immediately
> before one of your objects (or before the end of the slab if you're
> unlucky). ?You can still win because it doesn't matter which specific
> object you overflow, only that you overflow one of them.

Right. So you fill a slab with objects A that you want to overflow
(struct shmid_kernel in the example exploit) then free one of them,
allocate object B, smash it (and the next object), and find the
smashed object A.

But doesn't that make the whole /slab/procinfo discussion moot? You
can always use brute force to allocate N objects (where N is larger
than max objects in a slab) and then just free nth object that's most
likely to land on the slab you have full control over (as explained by
Matt).

Pekka

2011-03-04 21:44:09

by Dan Rosenberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, 2011-03-04 at 23:30 +0200, Pekka Enberg wrote:
> Right. So you fill a slab with objects A that you want to overflow
> (struct shmid_kernel in the example exploit) then free one of them,
> allocate object B, smash it (and the next object), and find the
> smashed object A.
>
> But doesn't that make the whole /slab/procinfo discussion moot? You
> can always use brute force to allocate N objects (where N is larger
> than max objects in a slab) and then just free nth object that's most
> likely to land on the slab you have full control over (as explained by
> Matt).
>
> Pekka

This is a good point, and one that I've come to accept as a result of
having this conversation. Consider the patch dropped, unless there are
other reasons I've missed. I still think it's worth brainstorming
techniques for hardening the kernel heap in ways that don't create
performance impact, but I admit that the presence or absence of this
debugging information isn't a crucial factor in successful exploitation.

Thanks,
Dan

2011-03-04 22:10:41

by Pekka Enberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

Hi Dan,

On Fri, Mar 4, 2011 at 11:44 PM, Dan Rosenberg <[email protected]> wrote:
> This is a good point, and one that I've come to accept as a result of
> having this conversation. ?Consider the patch dropped, unless there are
> other reasons I've missed. ?I still think it's worth brainstorming
> techniques for hardening the kernel heap in ways that don't create
> performance impact, but I admit that the presence or absence of this
> debugging information isn't a crucial factor in successful exploitation.

I can think of four things that will make things harder for the
attacker (in the order of least theoretical performance impact):

(1) disable slub merging

(2) pin down random objects in the slab during setup (i.e. don't
allow them to be allocated)

(3) randomize the initial freelist

(4) randomize padding between objects in a slab

AFAICT, all of them will make brute force attacks using the kernel
heap as an attack vector harder but won't prevent them.

Pekka

2011-03-04 22:14:59

by Pekka Enberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Sat, Mar 5, 2011 at 12:10 AM, Pekka Enberg <[email protected]> wrote:
> I can think of four things that will make things harder for the
> attacker (in the order of least theoretical performance impact):
>
> ?(1) disable slub merging
>
> ?(2) pin down random objects in the slab during setup (i.e. don't
> allow them to be allocated)
>
> ?(3) randomize the initial freelist
>
> ?(4) randomize padding between objects in a slab
>
> AFAICT, all of them will make brute force attacks using the kernel
> heap as an attack vector harder but won't prevent them.

There's also a fifth one:

(5) randomize slab page allocation order

which will make it harder to make sure you have full control over a
slab and figure out which allocation lands on it.

Pekka

2011-03-04 23:02:41

by Matt Mackall

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Sat, 2011-03-05 at 00:14 +0200, Pekka Enberg wrote:
> On Sat, Mar 5, 2011 at 12:10 AM, Pekka Enberg <[email protected]> wrote:
> > I can think of four things that will make things harder for the
> > attacker (in the order of least theoretical performance impact):
> >
> > (1) disable slub merging
> >
> > (2) pin down random objects in the slab during setup (i.e. don't
> > allow them to be allocated)
> >
> > (3) randomize the initial freelist
> >
> > (4) randomize padding between objects in a slab
> >
> > AFAICT, all of them will make brute force attacks using the kernel
> > heap as an attack vector harder but won't prevent them.
>
> There's also a fifth one:
>
> (5) randomize slab page allocation order
>
> which will make it harder to make sure you have full control over a
> slab and figure out which allocation lands on it.

I think the real issue here is that it's too easy to write code that
copies too many bytes from userspace. Every piece of code writes its own
bound checks on copy_from_user, for instance, and gets it wrong by
hitting signed/unsigned issues, alignment issues, etc. that are on the
very edge of the average C coder's awareness.

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.

I'm not really sure what that looks like yet, but a copy that does its
own bounds-checking seems like a start:

copy_from_user(dst, src, n, limit) # warning when limit is hit
copy_from_user_nw(dst, src, n, limit) # no warning version

--
Mathematics is the supreme nostalgia of our time.

2011-03-06 00:57:39

by Dan Rosenberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Sun, 2011-03-06 at 01:42 +0100, Jesper Juhl wrote:
> On Fri, 4 Mar 2011, Dan Rosenberg wrote:
>
> > On Fri, 2011-03-04 at 22:58 +0200, Pekka Enberg wrote:
> > > On Fri, Mar 4, 2011 at 10:37 PM, Dan Rosenberg <[email protected]> wrote:
> > > > This patch makes these techniques more difficult by making it hard to
> > > > know whether the last attacker-allocated object resides before a free or
> > > > allocated object. Especially with vulnerabilities that only allow one
> > > > attempt at exploitation before recovery is needed to avoid trashing too
> > > > much heap state and causing a crash, this could go a long way. I'd
> > > > still argue in favor of removing the ability to know how many objects
> > > > are used in a given slab, since randomizing objects doesn't help if you
> > > > know every object is allocated.
> > >
> > > So if the attacker knows every object is allocated, how does that help
> > > if we're randomizing the initial freelist?
> >
> > If you know you've got a slab completely full of your objects, then it
> > doesn't matter that they happened to be allocated in a random fashion -
> > they're still all allocated, and by freeing one of them and
> > reallocating, you'll still be next to your target.
> >
>
> But still, if randomizing allocations makes life just a little harder for
> attackers in some scenarios, why not just do it?
> Same with making /proc/slabinfo 0400, if it just makes things a little
> harder in a few cases, why not do it? It's not like a admin who needs
> /proc/slabinfo to have other permissions can't arrange for that.
>
> Having been employed as a systems administrator for many years and having
> seen many a box cracked, my oppinion is that every little bit helps. The
> kernel is currently not a hard target and everything we can do to harden
> it is a good thing (within reason of course).
>
> Why not just do both randomization and 0400 as a start? We can always
> harden further later.

I agree that there's no harm in these patches, and they might make it
(only) slightly harder in some cases, so yes, we might as well. I just
don't want to trick anyone into a false sense of security by thinking
that these measures by themselves are doing anything especially
substantial to prevent heap exploits. But as you say, it's a start.

Another hardening measure that's been mentioned before is validating the
address of each to-be-returned pointer during allocation, to avoid
attacks that rely on corrupting free list pointers (i.e. compare against
TASK_SIZE). But then we're talking about introducing additional
overhead into every single kmalloc() call.

-Dan

2011-03-06 01:09:48

by Matt Mackall

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Sun, 2011-03-06 at 01:42 +0100, Jesper Juhl wrote:
> On Fri, 4 Mar 2011, Dan Rosenberg wrote:
>
> > On Fri, 2011-03-04 at 22:58 +0200, Pekka Enberg wrote:
> > > On Fri, Mar 4, 2011 at 10:37 PM, Dan Rosenberg <[email protected]> wrote:
> > > > This patch makes these techniques more difficult by making it hard to
> > > > know whether the last attacker-allocated object resides before a free or
> > > > allocated object. Especially with vulnerabilities that only allow one
> > > > attempt at exploitation before recovery is needed to avoid trashing too
> > > > much heap state and causing a crash, this could go a long way. I'd
> > > > still argue in favor of removing the ability to know how many objects
> > > > are used in a given slab, since randomizing objects doesn't help if you
> > > > know every object is allocated.
> > >
> > > So if the attacker knows every object is allocated, how does that help
> > > if we're randomizing the initial freelist?
> >
> > If you know you've got a slab completely full of your objects, then it
> > doesn't matter that they happened to be allocated in a random fashion -
> > they're still all allocated, and by freeing one of them and
> > reallocating, you'll still be next to your target.
> >
>
> But still, if randomizing allocations makes life just a little harder for
> attackers in some scenarios, why not just do it?

Lemme guess, you work for the TSA?

As far as I can tell neither of the patches under discussion do anything
that couldn't be worked around by an exploit writer in the time it takes
to write this email. And the second attacker, of course, will have even
less trouble.

Putting trivial obstacles in the way of attackers accomplishes little
beyond annoying users.

--
Mathematics is the supreme nostalgia of our time.

2011-03-06 01:15:50

by Jesper Juhl

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Sat, 5 Mar 2011, Matt Mackall wrote:

> On Sun, 2011-03-06 at 01:42 +0100, Jesper Juhl wrote:
> > On Fri, 4 Mar 2011, Dan Rosenberg wrote:
> >
> > > On Fri, 2011-03-04 at 22:58 +0200, Pekka Enberg wrote:
> > > > On Fri, Mar 4, 2011 at 10:37 PM, Dan Rosenberg <[email protected]> wrote:
> > > > > This patch makes these techniques more difficult by making it hard to
> > > > > know whether the last attacker-allocated object resides before a free or
> > > > > allocated object. Especially with vulnerabilities that only allow one
> > > > > attempt at exploitation before recovery is needed to avoid trashing too
> > > > > much heap state and causing a crash, this could go a long way. I'd
> > > > > still argue in favor of removing the ability to know how many objects
> > > > > are used in a given slab, since randomizing objects doesn't help if you
> > > > > know every object is allocated.
> > > >
> > > > So if the attacker knows every object is allocated, how does that help
> > > > if we're randomizing the initial freelist?
> > >
> > > If you know you've got a slab completely full of your objects, then it
> > > doesn't matter that they happened to be allocated in a random fashion -
> > > they're still all allocated, and by freeing one of them and
> > > reallocating, you'll still be next to your target.
> > >
> >
> > But still, if randomizing allocations makes life just a little harder for
> > attackers in some scenarios, why not just do it?
>
> Lemme guess, you work for the TSA?
>
No. And now I actually feel slightly insulted.


> As far as I can tell neither of the patches under discussion do anything
> that couldn't be worked around by an exploit writer in the time it takes
> to write this email. And the second attacker, of course, will have even
> less trouble.
>
> Putting trivial obstacles in the way of attackers accomplishes little
> beyond annoying users.
>
If we annoy users I agree we shouldn't. If we don't annoy users (and don't
impact performance in any relevant way) then even trivial obstacles that
stop just a few exploits are worth it IMHO.


--
Jesper Juhl <[email protected]> http://www.chaosbits.net/
Plain text mails only, please.
Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html

2011-03-06 00:43:21

by Jesper Juhl

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, 4 Mar 2011, Dan Rosenberg wrote:

> On Fri, 2011-03-04 at 22:58 +0200, Pekka Enberg wrote:
> > On Fri, Mar 4, 2011 at 10:37 PM, Dan Rosenberg <[email protected]> wrote:
> > > This patch makes these techniques more difficult by making it hard to
> > > know whether the last attacker-allocated object resides before a free or
> > > allocated object. Especially with vulnerabilities that only allow one
> > > attempt at exploitation before recovery is needed to avoid trashing too
> > > much heap state and causing a crash, this could go a long way. I'd
> > > still argue in favor of removing the ability to know how many objects
> > > are used in a given slab, since randomizing objects doesn't help if you
> > > know every object is allocated.
> >
> > So if the attacker knows every object is allocated, how does that help
> > if we're randomizing the initial freelist?
>
> If you know you've got a slab completely full of your objects, then it
> doesn't matter that they happened to be allocated in a random fashion -
> they're still all allocated, and by freeing one of them and
> reallocating, you'll still be next to your target.
>

But still, if randomizing allocations makes life just a little harder for
attackers in some scenarios, why not just do it?
Same with making /proc/slabinfo 0400, if it just makes things a little
harder in a few cases, why not do it? It's not like a admin who needs
/proc/slabinfo to have other permissions can't arrange for that.

Having been employed as a systems administrator for many years and having
seen many a box cracked, my oppinion is that every little bit helps. The
kernel is currently not a hard target and everything we can do to harden
it is a good thing (within reason of course).

Why not just do both randomization and 0400 as a start? We can always
harden further later.

--
Jesper Juhl <[email protected]> http://www.chaosbits.net/
Plain text mails only, please.
Don't top-post http://www.catb.org/~esr/jargon/html/T/top-post.html

2011-03-06 00:13:35

by Theodore Ts'o

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Fri, Mar 04, 2011 at 05:02:36PM -0600, Matt Mackall wrote:
> copies too many bytes from userspace. Every piece of code writes its own
> bound checks on copy_from_user, for instance, and gets it wrong by
> hitting signed/unsigned issues, alignment issues, etc. that are on the
> very edge of the average C coder's awareness.

Agreed. Maybe something that would help is to have helper routines
which handle the most common patterns that driver writers need. Some
of the most common that I've seen from doing a quick survey are:

1) kmalloc() followed by copy_from_user()
2) kmem_cache_alloc() followed by copy_from_user()
3) copy_from_user() to a buffer allocated on the stack, where the length
is passed in from userspace, and the maximum expected input size is
declared by the driver. (Used by debugfs, proc, and sysfs handlers)
4) copy_from_user() to a structure allocated on the stack

If we had wrappers for the most common cases, then any cases that were
left that used copy_from_user() explicitly could be flagged and
checked by hand, since they would be exception, and not the rule.

- Ted

2011-03-06 13:20:51

by Alan

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

> If we had wrappers for the most common cases, then any cases that were
> left that used copy_from_user() explicitly could be flagged and
> checked by hand, since they would be exception, and not the rule.

Arjan's copy_from_user validation code already does verification checks
on the copies using gcc magic.

Some of the others might be useful - kmalloc_from_user() is a fairly
obvious interface, a copy_from_user_into() interface where you pass
the destination object and its actual length as well is mostly covered by
Arjan's stuff.

Alan

2011-03-07 14:56:55

by Dan Rosenberg

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Sun, 2011-03-06 at 13:19 +0000, Alan Cox wrote:
> > If we had wrappers for the most common cases, then any cases that were
> > left that used copy_from_user() explicitly could be flagged and
> > checked by hand, since they would be exception, and not the rule.
>
> Arjan's copy_from_user validation code already does verification checks
> on the copies using gcc magic.
>
> Some of the others might be useful - kmalloc_from_user() is a fairly
> obvious interface, a copy_from_user_into() interface where you pass
> the destination object and its actual length as well is mostly covered by
> Arjan's stuff.
>
> Alan

This is all worthwhile discussion, and a good implementation of these
kinds of features is available as part of grsecurity (PAX_USERCOPY) - it
provides additional bounds-checking for copy operations into both heap
and stack buffers. Rather than reinventing the wheel, perhaps it would
be a better use of time to extract this patch and make it suitable for
inclusion.

In the meantime, I'd like to get back to the original patch
(make /proc/slabinfo 0400), and the subsequent followup patch (randomize
free objects within a slab). While it's clear that these patches by
themselves will not entirely prevent kernel heap exploits, they both
seem to be sane improvements, won't significantly impact performance,
and shouldn't be more than a very minor inconvenience to some small
subset of normal users. In addition, the absence of these changes might
undermine future hardening improvements (e.g. with a more hardened heap,
the readability of /proc/slabinfo may be more necessary for successful
exploitation).

-Dan

2011-03-07 16:02:16

by Matt Mackall

[permalink] [raw]
Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Mon, 2011-03-07 at 09:56 -0500, Dan Rosenberg wrote:
> On Sun, 2011-03-06 at 13:19 +0000, Alan Cox wrote:
> > > If we had wrappers for the most common cases, then any cases that were
> > > left that used copy_from_user() explicitly could be flagged and
> > > checked by hand, since they would be exception, and not the rule.
> >
> > Arjan's copy_from_user validation code already does verification checks
> > on the copies using gcc magic.
> >
> > Some of the others might be useful - kmalloc_from_user() is a fairly
> > obvious interface, a copy_from_user_into() interface where you pass
> > the destination object and its actual length as well is mostly covered by
> > Arjan's stuff.
> >
> > Alan
>
> This is all worthwhile discussion, and a good implementation of these
> kinds of features is available as part of grsecurity (PAX_USERCOPY) - it
> provides additional bounds-checking for copy operations into both heap
> and stack buffers. Rather than reinventing the wheel, perhaps it would
> be a better use of time to extract this patch and make it suitable for
> inclusion.

Bounds-checking the existing generic functions is not at all the same,
and is in fact counterproductive. It says "go ahead, think even LESS
about getting your code right, because there's a (slow) safety net
built-in".

The above proposal is instead "copy these patterns that simplify your
code"

Consider time_after:

http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/include/linux/jiffies.h#L93

Before this code (now more than 10 years old), there was lots of code in
the kernel that manually compared time stamps and got it wrong. These
error would show up about 43 days later when someone on an Alpha would
get a panic. We eventually ended up setting the clock to wrap after only
5 minutes and hundreds of these bugs showed up. The fix was not to try
to catch unlikely timer values, but to instead make it easy to get the
code right.

> In the meantime, I'd like to get back to the original patch
> (make /proc/slabinfo 0400), and the subsequent followup patch (randomize
> free objects within a slab). While it's clear that these patches by
> themselves will not entirely prevent kernel heap exploits, they both
> seem to be sane improvements, won't significantly impact performance,
> and shouldn't be more than a very minor inconvenience to some small
> subset of normal users. In addition, the absence of these changes might
> undermine future hardening improvements (e.g. with a more hardened heap,
> the readability of /proc/slabinfo may be more necessary for successful
> exploitation).

If a "hardened heap" ever shows up which doesn't have the massive
overhead of a debugging heap and is thus interesting to the real world,
we can consider these changes then. But I won't be holding my breath.

The only method I know of to harden a heap that would prevent the
exploits we're looking at is basically CONFIG_PAGE_DEBUG: put each
object on a separate page and surround it by two not-present pages. Then
any overflow gets caught instantaneously by the MMU. Before anyone gets
excited about this approach: having 96-byte objects take 4k of physical
memory, 12k of virtual memory, and have massive TLB flushing overhead is
a great way to make your i7 feel like a 386.

Every other method that doesn't rely on hardware (eg redzoning) is only
defense against accidental overruns and will only catch problems long
after the fact. Further, if you can inject exploit code into a
neighboring object, you can probably properly repair the redzone while
you're at it.

The kind of randomization that defends address spaces won't work here.
That requires a vast amount of virtual memory to be any defense against
NOP sleds or equivalents. And we've only got physical space around the
size of a page to play with. If the attacker can control allocation of
lots of objects, we basically have to assume that space is crowded.

--
Mathematics is the supreme nostalgia of our time.

Subject: Re: [PATCH] Make /proc/slabinfo 0400

On Sun, 6 Mar 2011, Jesper Juhl wrote:

> > Putting trivial obstacles in the way of attackers accomplishes little
> > beyond annoying users.
> >
> If we annoy users I agree we shouldn't. If we don't annoy users (and don't
> impact performance in any relevant way) then even trivial obstacles that
> stop just a few exploits are worth it IMHO.

Randomizing affects performance. The current way of initialization for the
list of free objects was chosen because the processor can do effective
prefetching when the allocator serves objects following each other.