Page 1 of 1

/proc/self/maps and prefork-based apps

PostPosted: Sun Jul 12, 2009 12:16 am
by Grach
I had some thoughts about supposed address space layout leaks related to /proc/self/maps and I'm not sure whether or not I overestimate and understand the risks. So could you guys share your opinion, please?

The supposed problem is that a compromised less-privileged child process of a privileged parent process of prefork-based daemon can reveal /proc/self/maps to an attacker, and so the attacker could learn how to conduct ret2libc/information leak attacks against children or the parent (if there is a known vulnerability) with no need to defeat ASLR and with no need to deal with Grsecurity's bruteforce detering measures (that 30s fork() delay).

I understand that a child itself is a copy of its parent (except any post-fork() changes), and attacker could just dump the child's memory contents to get what he/she needs to defeat ASLR. But what if there's no way known to the attacker to read children's memory directly (PaX and Grsecurity does great job not to allow that), but is pretty feasible to trick children to reveal /proc/self/maps? That could be the way to defeat the parent's ASLR and/or to make exploitation of information leak vulnerabilities much easier.

For example:

1. Apache + mod_php/mod_perl/mod_whatever_language
An attacker could trick a script inside apache child process to reveal /proc/self/maps, so the parent's and children's ASLR could be defeated.

2. Nginx + symlink to /proc/self/maps
Nginx intentionally doesn't enforce any constraints when following any symlinks. Consider some web application to create a symlink to /proc/self/maps within the web site directory tree for the attacker to be able to get it by a simple GET request. The only thing that suddenly stops nginx from sending the contents of /proc/self/maps is the size of /proc/self/maps currently is being reported as 0, so nginx sends 0 bytes of data.

I also understand that access to /proc/*/maps can be restricted by RBAC, and that if prefork-based daemons or their children would be chrooted somewhere without /proc mounted, the problem is gone then. But doesn't all that seems more complicated in comparison to a sane default: don't allow /proc/self/maps reads? If that would cause problems for anyone, the sane default can be turned off by tweaking related sysctl variable, just like the rest of grsecurity options.

What's your opinion?

Re: /proc/self/maps and prefork-based apps

PostPosted: Tue Jul 14, 2009 5:32 pm
by PaX Team
1. /proc/self/maps cannot be restricted by default because glibc/FORTIFY_SOURCE=2 relies on it for the %n format string check (whether that was a good idea or not is irrelevant now, contemporary userland relies on it)

2. the proper way of fixing this userland issue is to turn the fork into a fork+execve sequence, something i think openssh does or can be told to do already. however it's not a trivial exercise in general when you consider stuff like apache+mod_php and an accelerator cache that stores code addresses in shared memory which won't quite work in differently randomized address spaces.

Re: /proc/self/maps and prefork-based apps

PostPosted: Thu Jul 16, 2009 5:51 am
by Grach
I see there's more need for /proc/self/maps in the glibc threading code. Sad... Well, thank you for clarification. I think I'll investigate the consequences of /proc/*/maps hiding and maybe will continue to use RBAC to hide them anyway.