Skip to contentSkip to conversation

mm: restrict access to slab files under procfs and sysfs

PATCH Applied Vasiliy Kulikov 8 participants 28 messages Sep 27, 2011 – Sep 30, 2011

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

PATCH 1/2 mm: restrict access to slab files under procfs and sysfs

Historically /proc/slabinfo and files under /sys/kernel/slab/* have world read permissions and are accessible to the world. slabinfo contains rather private information related both to the kernel and userspace tasks. Depending on the situation, it might reveal either private information per se or information useful to make another targeted attack. Some examples of what can be learned by reading/watching for /proc/slabinfo entries:

1) dentry (and different *inode*) number might reveal other processes fs activity. The number of dentry "active objects" doesn't strictly show file count opened/touched by a process, however, there is a good correlation between them. The patch "proc: force dcache drop on unauthorized access" relies on the privacy of dentry count.

2) different inode entries might reveal the same information as (1), but these are more fine granted counters. If a filesystem is mounted in a private mount point (or even a private namespace) and fs type differs from other mounted fs types, fs activity in this mount point/namespace is revealed. If there is a single ecryptfs mount point, the whole fs activity of a single user is revealed. Number of files in ecryptfs mount point is a private information per se.

3) fuse_* reveals number of files / fs activity of a user in a user private mount point. It is approx. the same severity as ecryptfs infoleak in (2).

4) sysfs_dir_cache similar to (2) reveals devices' addition/removal, which can be otherwise hidden by "chmod 0700 /sys/". With 0444 slabinfo the precise number of sysfs files is known to the world.

5) buffer_head might reveal some kernel activity. With other information leaks an attacker might identify what specific kernel routines generate buffer_head activity.

6) *kmalloc* infoleaks are very situational. Attacker should watch for the specific kmalloc size entry and filter the noise related to the unrelated kernel activity. If an attacker has relatively silent victim system, he might get rather precise counters.

Additional information sources might significantly increase the slabinfo infoleak benefits. E.g. if an attacker knows that the processes activity on the system is very low (only core daemons like syslog and cron), he may run setxid binaries / trigger local daemon activity / trigger network services activity / await sporadic cron jobs activity / etc. and get rather precise counters for fs and network activity of these privileged tasks, which is unknown otherwise.

Also hiding slabinfo and /sys/kernel/slab/* is a one step to complicate exploitation of kernel heap overflows (and possibly, other bugs). The related discussion:

http://thread.gmane.org/gmane.linux.kernel/1108378

To keep compatibility with old permission model where non-root monitoring daemon could watch for kernel memleaks though slabinfo one should do:

groupadd slabinfo
usermod -a -G slabinfo $MONITOR_USER

And add the following commands to init scripts (to mountall.conf in Ubuntu's upstart case):

chmod g+r /proc/slabinfo /sys/kernel/slab/*/* chgrp slabinfo /proc/slabinfo /sys/kernel/slab/*/*

---
 mm/slab.c |    2 +-
 mm/slub.c |    7 ++++---
 2 files changed, 5 insertions(+), 4 deletions(-)

--

mm/slab.c +1 -1
index 6d90a09..10a0052 100644
@@ -4584,7 +4584,7 @@ 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 +4 -3
index 9f662d7..527a66e 100644
@@ -4412,11 +4412,12 @@ struct slab_attribute {
 };
 
 #define SLAB_ATTR_RO(_name) \
-	static struct slab_attribute _name##_attr = __ATTR_RO(_name)
+	static struct slab_attribute _name##_attr = \
+	__ATTR(_name, 0400, _name##_show, NULL)
 
 #define SLAB_ATTR(_name) \
 	static struct slab_attribute _name##_attr =  \
-	__ATTR(_name, 0644, _name##_show, _name##_store)
+	__ATTR(_name, 0600, _name##_show, _name##_store)
 
 static ssize_t slab_size_show(struct kmem_cache *s, char *buf)
 {
@@ -5257,7 +5258,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

PATCH 2/2 mm: restrict access to /proc/meminfo

/proc/meminfo stores information related to memory pages usage, which may be used to monitor the number of objects in specific caches (and/or the changes of these numbers). This might reveal private information similar to /proc/slabinfo infoleaks. To remove the infoleak, just restrict meminfo to root. If it is used by unprivileged daemons, meminfo permissions can be altered the same way as slabinfo:

groupadd meminfo
usermod -a -G meminfo $MONITOR_USER
chmod g+r /proc/meminfo
chgrp meminfo /proc/meminfo

CC Kees Cook <[email protected]>
CC Dave Hansen <[email protected]>
CC Christoph Lameter <[email protected]>
CC Pekka Enberg <[email protected]>
CC Linus Torvalds <[email protected]>
CC David Rientjes <[email protected]>
CC Alan Cox <[email protected]>
---
 fs/proc/meminfo.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

--

fs/proc/meminfo.c +1 -1
index 5861741..949bdee 100644
@@ -187,7 +187,7 @@ static const struct file_operations meminfo_proc_fops = {
 
 static int __init proc_meminfo_init(void)
 {
-	proc_create("meminfo", 0, NULL, &meminfo_proc_fops);
+	proc_create("meminfo", S_IFREG | S_IRUSR, NULL, &meminfo_proc_fops);
 	return 0;
 }
 module_init(proc_meminfo_init);
#2 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

Quoted 7 lines · Vasiliy Kulikov

/proc/meminfo stores information related to memory pages usage, which may be used to monitor the number of objects in specific caches (and/or the changes of these numbers). This might reveal private information similar to /proc/slabinfo infoleaks. To remove the infoleak, just restrict meminfo to root. If it is used by unprivileged daemons, meminfo permissions can be altered the same way as slabinfo:

Quoted 5 lines

groupadd meminfo
usermod -a -G meminfo $MONITOR_USER
chmod g+r /proc/meminfo
chgrp meminfo /proc/meminfo

I guess the side-effect of this is that users without root will no longer report VM issues where "there's tons of freeable memory but my task got killed", "there's swap available but is unutilized in lowmem situations", etc. :)

Seriously, though, can't we just change the granularity of /proc/meminfo to be MB instead of KB or at least provide a separate file that is readable that does that? I can understand not exporting information on a page-level granularity but not giving users a way to determine the amount of free memory is a little extreme.

#3 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

Quoted 15 lines · David Rientjes
Quoted 7 lines · Vasiliy Kulikov

/proc/meminfo stores information related to memory pages usage, which may be used to monitor the number of objects in specific caches (and/or the changes of these numbers). This might reveal private information similar to /proc/slabinfo infoleaks. To remove the infoleak, just restrict meminfo to root. If it is used by unprivileged daemons, meminfo permissions can be altered the same way as slabinfo:

Quoted 5 lines

groupadd meminfo
usermod -a -G meminfo $MONITOR_USER
chmod g+r /proc/meminfo
chgrp meminfo /proc/meminfo

Quoted 4 lines

I guess the side-effect of this is that users without root will no longer report VM issues where "there's tons of freeable memory but my task got killed", "there's swap available but is unutilized in lowmem situations", etc. :)

Uhh, lost of "free" is rather significant.

Quoted 5 lines

Seriously, though, can't we just change the granularity of /proc/meminfo to be MB instead of KB or at least provide a separate file that is readable that does that? I can understand not exporting information on a page-level granularity but not giving users a way to determine the amount of free memory is a little extreme.

Probably it is the way to go. Users still may identify *some* information about the slab objects in question (ecryptfs, etc.), but it is more limited with MB granularity. Though, it is probably the only acceptable tradeoff in sense of backward compatibility.

Thank you,

Signature · 2 lines
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments
#4 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

In reply to Vasiliy Kulikov
Quoted 11 lines · Vasiliy Kulikov

/proc/meminfo stores information related to memory pages usage, which may be used to monitor the number of objects in specific caches (and/or the changes of these numbers). This might reveal private information similar to /proc/slabinfo infoleaks. To remove the infoleak, just restrict meminfo to root. If it is used by unprivileged daemons, meminfo permissions can be altered the same way as slabinfo:

groupadd meminfo
usermod -a -G meminfo $MONITOR_USER
chmod g+r /proc/meminfo
chgrp meminfo /proc/meminfo

Just to make it clear: since this patch breaks "free", I don't propose it anymore.

Quoted 27 lines
CC Kees Cook <[email protected]>
CC Dave Hansen <[email protected]>
CC Christoph Lameter <[email protected]>
CC Pekka Enberg <[email protected]>
CC Linus Torvalds <[email protected]>
CC David Rientjes <[email protected]>
CC Alan Cox <[email protected]>
---
 fs/proc/meminfo.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

--

fs/proc/meminfo.c +1 -1
index 5861741..949bdee 100644
@@ -187,7 +187,7 @@ static const struct file_operations meminfo_proc_fops = {
 
 static int __init proc_meminfo_init(void)
 {
-	proc_create("meminfo", 0, NULL, &meminfo_proc_fops);
+	proc_create("meminfo", S_IFREG | S_IRUSR, NULL, &meminfo_proc_fops);
 	return 0;
 }
 module_init(proc_meminfo_init);
Signature · 2 lines
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments
#5 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

Quoted 8 lines · Vasiliy Kulikov
Quoted 7 lines · Vasiliy Kulikov

/proc/meminfo stores information related to memory pages usage, which may be used to monitor the number of objects in specific caches (and/or the changes of these numbers). This might reveal private information similar to /proc/slabinfo infoleaks. To remove the infoleak, just restrict meminfo to root. If it is used by unprivileged daemons, meminfo permissions can be altered the same way as slabinfo:

Quoted 7 lines
Quoted 4 lines

groupadd meminfo
usermod -a -G meminfo $MONITOR_USER
chmod g+r /proc/meminfo
chgrp meminfo /proc/meminfo

Just to make it clear: since this patch breaks "free", I don't propose it anymore.

Viewing free memory is usually necessary to check on reclaim activities (things otherwise operating normally). "free" memory (in the sense of the memory that an application can still allocate) is not really displayed by free. Wish we had a new free that avoids all the misinterpretations.

Meminfo is also requires by vmstat.

If we want to go down this route then we need some sort of diagnostic group that a user must be part of in order to allow viewing of basic memory statistics.

#6 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

Quoted 7 lines · Christoph Lameter

Viewing free memory is usually necessary to check on reclaim activities (things otherwise operating normally). "free" memory (in the sense of the memory that an application can still allocate) is not really displayed by free. Wish we had a new free that avoids all the misinterpretations.

Meminfo is also requires by vmstat.

Even with the patch, you could still get all this information by summing up the per-node meminfo in /sys/devices/system/node/nodeX/meminfo. Non-root users certainly need to be able to use things like numactl and be able to specify their own mempolicies for NUMA machines, so limiting basic memory state information isn't going to work.

I'd much rather just convert everything to use MB rather than KB so you can't determine things at a page level. I think that gets us much closer to what the patch is intending to restrict. But I also expect some breakage from things that just expect meminfo to be in KB units without parsing what the kernel is exporting.

Quoted 4 lines

If we want to go down this route then we need some sort of diagnostic group that a user must be part of in order to allow viewing of basic memory statistics.

It'll turn into another one of our infinite number of capabilities. Does anything actually care about statistics at KB granularity these days?

#7 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

Quoted 2 lines · David Rientjes

It'll turn into another one of our infinite number of capabilities. Does anything actually care about statistics at KB granularity these days?

Changing that to MB may also break things. It may be better to have consistent system for access control to memory management counters that are not related to a process.

#8 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

Quoted 7 lines · Christoph Lameter
Quoted 2 lines · David Rientjes

It'll turn into another one of our infinite number of capabilities. Does anything actually care about statistics at KB granularity these days?

Changing that to MB may also break things. It may be better to have consistent system for access control to memory management counters that are not related to a process.

We could also just _effectively_ make it output in MB:

	foo = foo & ~(1<<20)

or align-up. We could also give the imprecise numbers to unprivileged users and let privileged ones see the page-level ones.

-- Dave

#9 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

Quoted 6 lines · On Wed, 28 Sep 2011 13:31:45 -0700 Dave Hansen <[email protected]> wrote:
Quoted 5 lines · Christoph Lameter
Quoted 3 lines · David Rientjes

It'll turn into another one of our infinite number of capabilities. Does anything actually care about statistics at KB granularity these days?

Quoted 7 lines
Quoted 3 lines

Changing that to MB may also break things. It may be better to have consistent system for access control to memory management counters that are not related to a process.

We could also just _effectively_ make it output in MB:

	foo = foo & ~(1<<20)

I do not think that does what you intend 8)

I do like the idea - it avoids any interfaces vanishing and surprise breakages while only CAP_SYS_whatever needs the real numbers

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

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

In reply to Dave Hansen
Quoted 5 lines · Dave Hansen

We could also just _effectively_ make it output in MB:

	foo = foo & ~(1<<20)

or align-up.

I think we want align-up here, there's a bunch of fields that code probably expects to be non-zero on a system that's finished booting...

Quoted 2 lines

We could also give the imprecise numbers to unprivileged users and let privileged ones see the page-level ones.

That also sounds like a good idea.

#11 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

Quoted 4 lines · On Wed, 28 Sep 2011, [email protected] wrote:
Quoted 2 lines

We could also give the imprecise numbers to unprivileged users and let privileged ones see the page-level ones.

That also sounds like a good idea.

Uhh... Another source of confusions for the uninitiated.

#12 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

In reply to David Rientjes
Quoted 5 lines · David Rientjes

I'd much rather just convert everything to use MB rather than KB so you can't determine things at a page level. I think that gets us much closer to what the patch is intending to restrict. But I also expect some breakage from things that just expect meminfo to be in KB units without parsing what the kernel is exporting.

I'm not convinced with rounding the information to MBs. The attacker still may fill slabs with new objects to trigger new slab pages allocations. He will be able to see when this MB-granularity barrier is overrun thus seeing how many kbs there were before:

old = new - filled_obj_size_sum

As `new' is just increased, it means it is known with KB granularity, not MB. By counting used slab objects he learns filled_obj_size_sum.

So, rounding gives us nothing, but obscurity.

Thanks,

Signature · 2 lines
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments
#13 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

Quoted 11 lines · Vasiliy Kulikov

I'm not convinced with rounding the information to MBs. The attacker still may fill slabs with new objects to trigger new slab pages allocations. He will be able to see when this MB-granularity barrier is overrun thus seeing how many kbs there were before:

old = new - filled_obj_size_sum

As `new' is just increased, it means it is known with KB granularity, not MB. By counting used slab objects he learns filled_obj_size_sum.

So, rounding gives us nothing, but obscurity.

I'll agree that it doesn't fundamentally fix anything. But, it does make an attack more difficult in the real world. There's a reason that real-world attackers are going after slabinfo: it's a fundamentally *BETTER* than meminfo as a tool with which to aim an attack. A MB-rounded meminfo is also fundamentally *BETTER* than a PAGE_SIZE-rounded meminfo. I find it hard to call this "nothing".

Anyway... I'm working on a patch. Will post soon.

-- Dave

#14 lore raw

Re: [kernel-hardening] Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

Quoted 8 lines · Dave Hansen
Quoted 7 lines · Vasiliy Kulikov

I'm not convinced with rounding the information to MBs. The attacker still may fill slabs with new objects to trigger new slab pages allocations. He will be able to see when this MB-granularity barrier is overrun thus seeing how many kbs there were before:

old = new - filled_obj_size_sum

Quoted 7 lines
Quoted 4 lines

As `new' is just increased, it means it is known with KB granularity, not MB. By counting used slab objects he learns filled_obj_size_sum.

So, rounding gives us nothing, but obscurity.

I'll agree that it doesn't fundamentally fix anything. But, it does make an attack more difficult in the real world.

No, it doesn't. An attacker is able to simply add/remove objects from slab and get the precise numbers. The only thing it takes some time, but the delay is negligible. It neither eliminates the whole attack vector in specific cases nor makes the attacks probabilistic.

Quoted 3 lines

There's a reason that
real-world attackers are going after slabinfo: it's a fundamentally *BETTER* than meminfo as a tool with which to aim an attack.

Agreed, it gives much more information.

Quoted 3 lines

A
MB-rounded meminfo is also fundamentally *BETTER* than a PAGE_SIZE-rounded meminfo. I find it hard to call this "nothing".

Could you elaborate? As I've tried to describe above, an attacker still may recover the numbers.

Thanks,

Signature · 2 lines
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments
#15 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

In reply to Vasiliy Kulikov
Quoted 4 lines · Vasiliy Kulikov

As `new' is just increased, it means it is known with KB granularity, not MB. By counting used slab objects he learns filled_obj_size_sum.

So, rounding gives us nothing, but obscurity.

Yes, but if he has an exploit that requires using up (for example) exactly 31 objects in the slab, he may now know that a new slab got allocated to push it over the MB boundary. So he knows there's exactly one object in that new slab.

But now he has to fly blind for the next 30 because the numbers will display exactly the same, and he can't correct for somebody else allocating one so he needs to only allocate 29...

#16 lore raw

Re: [kernel-hardening] Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

Quoted 3 lines · On Thu, Sep 29, 2011 at 12:57 -0400, [email protected] wrote:

But now he has to fly blind for the next 30 because the numbers will display exactly the same, and he can't correct for somebody else allocating one so he needs to only allocate 29...

You're still talking about "slabinfo", which is already restricted.

And meminfo can be still learned with the same race window (ala seq lock):

    prepare_stuff();
    fill_slabs(); // Here we know counters with KB granularity
    while (number_is_not_ok()) {
        prepare_stuff();
        fill_slabs();
    }
    do_exploit();

Thanks,

Signature · 2 lines
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments
#17 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

In reply to Vasiliy Kulikov
Quoted 12 lines · Vasiliy Kulikov
Quoted 5 lines · David Rientjes

I'd much rather just convert everything to use MB rather than KB so you can't determine things at a page level. I think that gets us much closer to what the patch is intending to restrict. But I also expect some breakage from things that just expect meminfo to be in KB units without parsing what the kernel is exporting.

I'm not convinced with rounding the information to MBs. The attacker still may fill slabs with new objects to trigger new slab pages allocations. He will be able to see when this MB-granularity barrier is overrun thus seeing how many kbs there were before:

Quoted 4 lines

old = new - filled_obj_size_sum

As `new' is just increased, it means it is known with KB granularity, not MB. By counting used slab objects he learns filled_obj_size_sum.

s/filled_obj_size_sum/old/ of course.

Quoted 3 lines

So, rounding gives us nothing, but obscurity.

Thanks,

Signature · 2 lines
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments
#18 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

In reply to Vasiliy Kulikov
Quoted 8 lines · On Tue, 27 Sep 2011 23:38:10 +0400 Vasiliy Kulikov <[email protected]> wrote:
Quoted 7 lines · Vasiliy Kulikov

/proc/meminfo stores information related to memory pages usage, which may be used to monitor the number of objects in specific caches (and/or the changes of these numbers). This might reveal private information similar to /proc/slabinfo infoleaks. To remove the infoleak, just restrict meminfo to root. If it is used by unprivileged daemons, meminfo permissions can be altered the same way as slabinfo:

Quoted 7 lines
Quoted 4 lines

groupadd meminfo
usermod -a -G meminfo $MONITOR_USER
chmod g+r /proc/meminfo
chgrp meminfo /proc/meminfo

Just to make it clear: since this patch breaks "free", I don't propose it anymore.

It will break top(1) too. It isn't my favoritest-ever patch :)

#19 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

Quoted 16 lines · Andrew Morton
Quoted 13 lines · On Tue, 27 Sep 2011 23:38:10 +0400 Vasiliy Kulikov <[email protected]> wrote:
Quoted 11 lines · Vasiliy Kulikov

/proc/meminfo stores information related to memory pages usage, which may be used to monitor the number of objects in specific caches (and/or the changes of these numbers). This might reveal private information similar to /proc/slabinfo infoleaks. To remove the infoleak, just restrict meminfo to root. If it is used by unprivileged daemons, meminfo permissions can be altered the same way as slabinfo:

groupadd meminfo
usermod -a -G meminfo $MONITOR_USER
chmod g+r /proc/meminfo
chgrp meminfo /proc/meminfo

Quoted 4 lines
Quoted 2 lines

Just to make it clear: since this patch breaks "free", I don't propose it anymore.

It will break top(1) too. It isn't my favoritest-ever patch :)

FWIW, I consider it as a top's bug. It tries to handle failed open(), but forgets to reset tty mode.

Anyway, how do we expect userspace apps handle meminfo data? Is it used as a debugging information only? E.g. admin wants to see how much memory is used, monitoring daemon looks for memleaks and running out of memory (1)? Or the numbers are used in some calculations e.g. calculation of approximate number of parallel processes to spawn (2)?

If we care about (1) only, we may do the same as we do with kernel pointers, i.e. show zeroes to non-CAP_SYS_ADMIN users (plus emit a sinlge warning in syslog). It will not break top, and top will simply show zero counters. Admins who still want to read this information as non-root should chmod/chgrp it in boot scripts. (And distros should provide a default "debugging" group for these needs.)

If we care about (2), we should pass non-zero counters, but imagine some default values, which will result in sane processes numbers. But it might depend on specific applications, I'm not aware whether (2) is real.

Other ideas?

Signature · 2 lines
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments
#20 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

Quoted 26 lines · On Fri, 30 Sep 2011 23:53:29 +0400 Vasiliy Kulikov <[email protected]> wrote:
Quoted 16 lines · Andrew Morton
Quoted 13 lines · On Tue, 27 Sep 2011 23:38:10 +0400 Vasiliy Kulikov <[email protected]> wrote:
Quoted 11 lines · Vasiliy Kulikov

/proc/meminfo stores information related to memory pages usage, which may be used to monitor the number of objects in specific caches (and/or the changes of these numbers). This might reveal private information similar to /proc/slabinfo infoleaks. To remove the infoleak, just restrict meminfo to root. If it is used by unprivileged daemons, meminfo permissions can be altered the same way as slabinfo:

groupadd meminfo
usermod -a -G meminfo $MONITOR_USER
chmod g+r /proc/meminfo
chgrp meminfo /proc/meminfo

Quoted 4 lines
Quoted 2 lines

Just to make it clear: since this patch breaks "free", I don't propose it anymore.

It will break top(1) too. It isn't my favoritest-ever patch :)

FWIW, I consider it as a top's bug. It tries to handle failed open(), but forgets to reset tty mode.

Quoted 5 lines

Anyway, how do we expect userspace apps handle meminfo data? Is it used as a debugging information only? E.g. admin wants to see how much memory is used, monitoring daemon looks for memleaks and running out of memory (1)? Or the numbers are used in some calculations e.g. calculation of approximate number of parallel processes to spawn (2)?

Well. Both, of course. And more. eg, monitor it and send an SMS message to the admin when things start to go wrong.

Quoted 6 lines

If we care about (1) only, we may do the same as we do with kernel pointers, i.e. show zeroes to non-CAP_SYS_ADMIN users (plus emit a sinlge warning in syslog). It will not break top, and top will simply show zero counters. Admins who still want to read this information as non-root should chmod/chgrp it in boot scripts. (And distros should provide a default "debugging" group for these needs.)

meminfo has been around for a very long time and is a convenient and centralised point for collecting memory data. There will be a large number of apps/scripts/tools out there which use it. Many of these won't even be available to us.

All of which makes it very hard for us to predict how much breakage we will cause.

Quoted 7 lines

If we care about (2), we should pass non-zero counters, but imagine some default values, which will result in sane processes numbers. But it might depend on specific applications, I'm not aware whether (2) is real.

Other ideas?

echo "chmod 0400 /proc/meminfo" >> /etc/rc.local

#21 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

Quoted 14 lines · Andrew Morton

meminfo has been around for a very long time and is a convenient and centralised point for collecting memory data. There will be a large number of apps/scripts/tools out there which use it. Many of these won't even be available to us.

All of which makes it very hard for us to predict how much breakage we will cause.

Quoted 6 lines

If we care about (2), we should pass non-zero counters, but imagine some default values, which will result in sane processes numbers. But it might depend on specific applications, I'm not aware whether (2) is real.

Quoted 3 lines
Quoted 1 line

Other ideas?

echo "chmod 0400 /proc/meminfo" >> /etc/rc.local

How will it help to fix apps' dependencies on meminfo?

Signature · 2 lines
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments
#22 lore raw

Re: [PATCH 2/2] mm: restrict access to /proc/meminfo

In reply to Andrew Morton

I stuck a printk in there. It's not exactly called 100x a second, but there were 5 distinct users just for me to boot and ssh in:

[    3.130408] meminfo read called by: 'udevd' 1
[    3.326649] meminfo read called by: 'dhclient-script' 2
[    4.624943] meminfo read called by: 'klogd' 3
[    8.008019] meminfo read called by: 'dhclient-script' 4
[    8.083091] meminfo read called by: 'ps' 5
[   48.171038] meminfo read called by: 'bash' 6

Granted, those were likely privileged. But, that's a good list of processes that I would rather not see break.

-- Dave

reviewer Acked-by on v1 1/2
#23 lore raw
In reply to Vasiliy Kulikov

This also needs to other /proc files I believe,

Possible candidates:

christoph@oldy:~/n/linux-2.6$ grep proc_create mm/*
mm/swapfile.c:	proc_create("swaps", 0, NULL, &proc_swaps_operations);
mm/vmstat.c:	proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);
mm/vmstat.c:	proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops);
mm/vmstat.c:	proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations);
mm/vmstat.c:	proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations);

vmstat and zoneinfo in particular give similar information to what is revealed through the slab proc files.

#24 lore raw
Quoted 11 lines · Christoph Lameter

Possible candidates:

christoph@oldy:~/n/linux-2.6$ grep proc_create mm/*
mm/swapfile.c:	proc_create("swaps", 0, NULL, &proc_swaps_operations);
mm/vmstat.c:	proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);
mm/vmstat.c:	proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops);
mm/vmstat.c:	proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations);
mm/vmstat.c:	proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations);

vmstat and zoneinfo in particular give similar information to what is revealed through the slab proc files.

Do you know whether these files are actively used? I don't want to break tools like "free" or "top". In this case we'll have to discover another way to limit this information.

Thank you!

Signature · 2 lines
Vasiliy Kulikov
http://www.openwall.com - bringing security into open computing environments
#25 lore raw
Quoted 10 lines · Vasiliy Kulikov
Quoted 9 lines · Christoph Lameter

Possible candidates:

christoph@oldy:~/n/linux-2.6$ grep proc_create mm/*
mm/swapfile.c:	proc_create("swaps", 0, NULL, &proc_swaps_operations);
mm/vmstat.c:	proc_create("buddyinfo", S_IRUGO, NULL, &fragmentation_file_operations);
mm/vmstat.c:	proc_create("pagetypeinfo", S_IRUGO, NULL, &pagetypeinfo_file_ops);
mm/vmstat.c:	proc_create("vmstat", S_IRUGO, NULL, &proc_vmstat_file_operations);
mm/vmstat.c:	proc_create("zoneinfo", S_IRUGO, NULL, &proc_zoneinfo_file_operations);
Quoted 6 lines
Quoted 2 lines

vmstat and zoneinfo in particular give similar information to what is revealed through the slab proc files.

Do you know whether these files are actively used? I don't want to break tools like "free" or "top". In this case we'll have to discover another way to limit this information.

top uses per process information. Tried an strace and I see no access to vmstat or zoneinfo.

free uses /proc/meminfo not vmstat or zoneinfo. Since you already have a patch that limits /proc/meminfo access there is already an issue there.

reviewer Acked-by on v1 1/2
#26 lore raw
In reply to Vasiliy Kulikov
Quoted 68 lines · Vasiliy Kulikov

Historically /proc/slabinfo and files under /sys/kernel/slab/* have world read permissions and are accessible to the world. slabinfo contains rather private information related both to the kernel and userspace tasks. Depending on the situation, it might reveal either private information per se or information useful to make another targeted attack. Some examples of what can be learned by reading/watching for /proc/slabinfo entries:

1) dentry (and different *inode*) number might reveal other processes fs activity. The number of dentry "active objects" doesn't strictly show file count opened/touched by a process, however, there is a good correlation between them. The patch "proc: force dcache drop on unauthorized access" relies on the privacy of dentry count.

2) different inode entries might reveal the same information as (1), but these are more fine granted counters. If a filesystem is mounted in a private mount point (or even a private namespace) and fs type differs from other mounted fs types, fs activity in this mount point/namespace is revealed. If there is a single ecryptfs mount point, the whole fs activity of a single user is revealed. Number of files in ecryptfs mount point is a private information per se.

3) fuse_* reveals number of files / fs activity of a user in a user private mount point. It is approx. the same severity as ecryptfs infoleak in (2).

4) sysfs_dir_cache similar to (2) reveals devices' addition/removal, which can be otherwise hidden by "chmod 0700 /sys/". With 0444 slabinfo the precise number of sysfs files is known to the world.

5) buffer_head might reveal some kernel activity. With other information leaks an attacker might identify what specific kernel routines generate buffer_head activity.

6) *kmalloc* infoleaks are very situational. Attacker should watch for the specific kmalloc size entry and filter the noise related to the unrelated kernel activity. If an attacker has relatively silent victim system, he might get rather precise counters.

Additional information sources might significantly increase the slabinfo infoleak benefits. E.g. if an attacker knows that the processes activity on the system is very low (only core daemons like syslog and cron), he may run setxid binaries / trigger local daemon activity / trigger network services activity / await sporadic cron jobs activity / etc. and get rather precise counters for fs and network activity of these privileged tasks, which is unknown otherwise.

Also hiding slabinfo and /sys/kernel/slab/* is a one step to complicate exploitation of kernel heap overflows (and possibly, other bugs). The related discussion:

http://thread.gmane.org/gmane.linux.kernel/1108378

To keep compatibility with old permission model where non-root monitoring daemon could watch for kernel memleaks though slabinfo one should do:

groupadd slabinfo
usermod -a -G slabinfo $MONITOR_USER

And add the following commands to init scripts (to mountall.conf in Ubuntu's upstart case):

chmod g+r /proc/slabinfo /sys/kernel/slab/*/* chgrp slabinfo /proc/slabinfo /sys/kernel/slab/*/*

Quoted 9 lines
Applied
#27 lore raw
Quoted 80 lines · David Rientjes
Quoted 68 lines · Vasiliy Kulikov

Historically /proc/slabinfo and files under /sys/kernel/slab/* have world read permissions and are accessible to the world.  slabinfo contains rather private information related both to the kernel and userspace tasks.  Depending on the situation, it might reveal either private information per se or information useful to make another targeted attack.  Some examples of what can be learned by reading/watching for /proc/slabinfo entries:

1) dentry (and different *inode*) number might reveal other processes fs activity.  The number of dentry "active objects" doesn't strictly show file count opened/touched by a process, however, there is a good correlation between them.  The patch "proc: force dcache drop on unauthorized access" relies on the privacy of dentry count.

2) different inode entries might reveal the same information as (1), but these are more fine granted counters.  If a filesystem is mounted in a private mount point (or even a private namespace) and fs type differs from other mounted fs types, fs activity in this mount point/namespace is revealed.  If there is a single ecryptfs mount point, the whole fs activity of a single user is revealed.  Number of files in ecryptfs mount point is a private information per se.

3) fuse_* reveals number of files / fs activity of a user in a user private mount point.  It is approx. the same severity as ecryptfs infoleak in (2).

4) sysfs_dir_cache similar to (2) reveals devices' addition/removal, which can be otherwise hidden by "chmod 0700 /sys/".  With 0444 slabinfo the precise number of sysfs files is known to the world.

5) buffer_head might reveal some kernel activity.  With other information leaks an attacker might identify what specific kernel routines generate buffer_head activity.

6) *kmalloc* infoleaks are very situational.  Attacker should watch for the specific kmalloc size entry and filter the noise related to the unrelated kernel activity.  If an attacker has relatively silent victim system, he might get rather precise counters.

Additional information sources might significantly increase the slabinfo infoleak benefits.  E.g. if an attacker knows that the processes activity on the system is very low (only core daemons like syslog and cron), he may run setxid binaries / trigger local daemon activity / trigger network services activity / await sporadic cron jobs activity / etc. and get rather precise counters for fs and network activity of these privileged tasks, which is unknown otherwise.

Also hiding slabinfo and /sys/kernel/slab/* is a one step to complicate exploitation of kernel heap overflows (and possibly, other bugs).  The related discussion:

http://thread.gmane.org/gmane.linux.kernel/1108378

To keep compatibility with old permission model where non-root monitoring daemon could watch for kernel memleaks though slabinfo one should do:

    groupadd slabinfo
    usermod -a -G slabinfo $MONITOR_USER

And add the following commands to init scripts (to mountall.conf in Ubuntu's upstart case):

    chmod g+r /proc/slabinfo /sys/kernel/slab/*/* chgrp slabinfo /proc/slabinfo /sys/kernel/slab/*/*

Quoted 9 lines
Quoted 1 line

Applied, thanks!