Skip to contentSkip to conversation

Make /proc/slabinfo 0400

PATCH In review Dan Rosenberg 9 participants 38 messages Mar 3, 2011 – Mar 7, 2011

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 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.

---
 mm/slab.c |    3 ++-
 mm/slub.c |    2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)
mm/slab.c +2 -1
index 37961d1..7f719f6 100644
@@ -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
mm/slub.c +1 -1
index e15aa7f..5f57834 100644
@@ -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);
#1 lore raw

mm/slub.c static const struct file_operations proc_slabinfo_operations = { · line 4697

Quoted 11 lines · Dan Rosenberg
mm/slub.c +1 -1
@@ -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

#2 lore raw
Quoted 8 lines

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.

Quoted 1 line

-- Dave

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#3 lore raw
In reply to Dan Rosenberg
Quoted 6 lines · Dan Rosenberg

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.

Signature · 1 line
Mathematics is the supreme nostalgia of our time.
#4 lore raw
Quoted 9 lines

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.

Quoted 3 lines

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

Quoted 2 lines
Signature · 1 line
Mathematics is the supreme nostalgia of our time.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#5 lore raw
Quoted 9 lines · Dan Rosenberg
Quoted 8 lines

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.

Quoted 8 lines

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..

Quoted 6 lines
Quoted 3 lines

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.

Signature · 9 lines
Mathematics is the supreme nostalgia of our time.


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#6 lore raw
Quoted 7 lines

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/

Quoted 8 lines

..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.

Quoted 4 lines

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.

Quoted 4 lines
Quoted 4 lines
Quoted 3 lines

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

Quoted 9 lines
Quoted 2 lines

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

Quoted 2 lines
Signature · 1 line
Mathematics is the supreme nostalgia of our time.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#7 lore raw
Quoted 60 lines · Dan Rosenberg
Quoted 6 lines

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/

Quoted 8 lines

..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.

Quoted 4 lines

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.

Quoted 4 lines
Quoted 4 lines
Quoted 3 lines

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

Quoted 9 lines
Quoted 2 lines

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.

Quoted 5 lines

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.

Signature · 1 line
Mathematics is the supreme nostalgia of our time.
#8 lore raw
Quoted 5 lines · Matt Mackall
Quoted 5 lines

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

#9 lore raw
In reply to Dan Rosenberg
Quoted 5 lines · Dan Rosenberg

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

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#10 lore raw
Quoted 5 lines · Dan Rosenberg
Quoted 5 lines

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.

Quoted 6 lines · Theodore Tso

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?

Quoted 4 lines · Theodore Tso

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.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#11 lore raw
Quoted 8 lines · Pekka Enberg
Quoted 6 lines · Theodore Tso

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.

Quoted 4 lines

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

#12 lore raw
Quoted 6 lines · Dave Hansen

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

#13 lore raw
Quoted 24 lines · Linus Torvalds
Quoted 6 lines · Dave Hansen

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.

Quoted 6 lines

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.

Signature · 9 lines
Mathematics is the supreme nostalgia of our time.


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#14 lore raw
Quoted 9 lines · Matt Mackall
Quoted 6 lines

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

From cd1e20fb8eb44627fa5ccebc8a2803c1fd7bf7ba Mon Sep 17 00:00:00 2001
From: Pekka Enberg <[email protected]>
Date: Fri, 4 Mar 2011 21:28:56 +0200
Subject: [PATCH] SLUB: Randomize object layout in slabs

---
 mm/slub.c |   45 +++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 45 insertions(+), 0 deletions(-)
mm/slub.c +45 -0
index e15aa7f..1837fe3 100644
@@ -27,6 +27,7 @@
 #include <linux/memory.h>
 #include <linux/math64.h>
 #include <linux/fault-inject.h>
+#include <linux/random.h>
 
 #include <trace/events/kmem.h>
 
@@ -1183,6 +1184,46 @@ static void setup_object(struct kmem_cache *s, struct page *page,
 		s->ctor(object);
 }
 
+static bool setup_slab_randomized(struct kmem_cache *s, struct page *page, gfp_t flags)
+{
+	unsigned long bitmap[8];
+	size_t bitmap_size;
+	void *last, *start;
+
+	bitmap_size = BITS_TO_LONGS(page->objects) * sizeof(unsigned long);
+
+	if (ARRAY_SIZE(bitmap) * sizeof(unsigned long) < bitmap_size)
+		return false;
+
+	bitmap_fill(bitmap, page->objects);
+
+	start = page_address(page);
+
+	last = start;
+	while (!bitmap_empty(bitmap, page->objects)) {
+		unsigned long idx;
+		void *p;
+
+		idx	= get_random_int() % page->objects;
+
+		idx	= find_next_bit(bitmap, page->objects, idx);
+
+		if (idx >= page->objects)
+			continue;
+
+		clear_bit(idx, bitmap);
+
+		p = start + idx * s->size;
+		setup_object(s, page, last);
+		set_freepointer(s, last, p);
+		last = p;
+	}
+	setup_object(s, page, last);
+	set_freepointer(s, last, NULL);
+
+	return true;
+}
+
 static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
 {
 	struct page *page;
@@ -1206,6 +1247,9 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
 	if (unlikely(s->flags & SLAB_POISON))
 		memset(start, POISON_INUSE, PAGE_SIZE << compound_order(page));
 
+	if (setup_slab_randomized(s, page, flags))
+		goto done; 
+
 	last = start;
 	for_each_object(p, s, start, page->objects) {
 		setup_object(s, page, last);
@@ -1215,6 +1259,7 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
 	setup_object(s, page, last);
 	set_freepointer(s, last, NULL);
 
+done:
 	page->freelist = start;
 	page->inuse = 0;
 out:
Signature · 1 line
1.7.0.4
#15 lore raw
Quoted 8 lines · Pekka Enberg
Quoted 7 lines · Matt Mackall
Quoted 6 lines

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).

Quoted 7 lines
Quoted 2 lines

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.

Signature · 1 line
Mathematics is the supreme nostalgia of our time.
#16 lore raw
Quoted 17 lines · Matt Mackall
Quoted 8 lines · Pekka Enberg
Quoted 7 lines · Matt Mackall
Quoted 6 lines

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).

Quoted 7 lines
Quoted 2 lines

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.

Quoted 8 lines

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

Quoted 2 lines
Signature · 1 line
Mathematics is the supreme nostalgia of our time.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#17 lore raw
Quoted 24 lines · Matt Mackall
Quoted 24 lines · Pekka Enberg
Quoted 8 lines · Matt Mackall
Quoted 7 lines
Quoted 6 lines

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).

Quoted 7 lines
Quoted 2 lines

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.

Quoted 5 lines · Dan Rosenberg

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

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#18 lore raw
Quoted 33 lines · Pekka Enberg
Quoted 24 lines · Matt Mackall
Quoted 24 lines · Pekka Enberg
Quoted 8 lines · Matt Mackall
Quoted 7 lines
Quoted 6 lines

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).

Quoted 7 lines
Quoted 2 lines

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.

Quoted 5 lines · Dan Rosenberg

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.

Quoted 6 lines

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

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#19 lore raw

Hi Dan,

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

Quoted 9 lines · Dan Rosenberg

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

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#20 lore raw
Quoted 5 lines · Pekka Enberg

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.

Quoted 7 lines

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

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#21 lore raw

Hi Dan,

Quoted 6 lines · Dan Rosenberg

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

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#22 lore raw
Quoted 8 lines · Pekka Enberg

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)

Quoted 6 lines

 (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

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#23 lore raw
Quoted 16 lines · Pekka Enberg
Quoted 8 lines · Pekka Enberg

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)

Quoted 6 lines

(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.

Quoted 6 lines

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

Signature · 1 line
Mathematics is the supreme nostalgia of our time.
#24 lore raw
Quoted 4 lines · Matt Mackall

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

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#25 lore raw
Quoted 3 lines

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

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#26 lore raw
Quoted 7 lines · Alan Cox
Quoted 3 lines

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.

Quoted 6 lines

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

#27 lore raw
Quoted 13 lines · Dan Rosenberg
Quoted 12 lines · Alan Cox
Quoted 3 lines

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.

Quoted 8 lines
Quoted 1 line

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.

Quoted 10 lines

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.

Signature · 1 line
Mathematics is the supreme nostalgia of our time.
#28 lore raw
In reply to Pekka Enberg
Quoted 11 lines · Pekka Enberg
Quoted 9 lines · Matt Mackall
Quoted 6 lines

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.

Quoted 6 lines

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

#29 lore raw
Quoted 8 lines · Dan Rosenberg

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?

#30 lore raw
Quoted 10 lines · Pekka Enberg
Quoted 8 lines · Dan Rosenberg

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.

Quoted 2 lines

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.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#31 lore raw
Quoted 11 lines · Dan Rosenberg
Quoted 10 lines · Pekka Enberg
Quoted 8 lines · Dan Rosenberg

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.

Quoted 8 lines
Quoted 2 lines

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.

Signature · 10 lines
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

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#32 lore raw
Quoted 28 lines · Jesper Juhl
Quoted 11 lines · Dan Rosenberg
Quoted 10 lines · Pekka Enberg
Quoted 8 lines · Dan Rosenberg

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.

Quoted 8 lines
Quoted 2 lines

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.

Quoted 7 lines

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

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#33 lore raw
In reply to Jesper Juhl
Quoted 16 lines · Jesper Juhl
Quoted 14 lines · Dan Rosenberg
Quoted 12 lines · Pekka Enberg
Quoted 8 lines · Dan Rosenberg

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?

Quoted 8 lines
Quoted 5 lines

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.

Signature · 9 lines
Mathematics is the supreme nostalgia of our time.


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#34 lore raw
Quoted 23 lines · Matt Mackall
Quoted 22 lines · Jesper Juhl
Quoted 19 lines · Dan Rosenberg
Quoted 10 lines · Pekka Enberg
Quoted 8 lines · Dan Rosenberg

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.

Quoted 2 lines

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.

Quoted 5 lines
Quoted 2 lines

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.

Quoted 8 lines

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.

Signature · 10 lines
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

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#35 lore raw
Quoted 6 lines · Jesper Juhl
Quoted 3 lines

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.

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>

#36 lore raw
In reply to Pekka Enberg
Quoted 10 lines · Pekka Enberg
Quoted 8 lines · Dan Rosenberg

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.

Quoted 2 lines

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.

Signature · 9 lines
Mathematics is the supreme nostalgia of our time.


--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected].  For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
#37 lore raw
In reply to Theodore Tso
Quoted 2 lines

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

--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>