Bug 139475 - Kernel: Privilege escalation through prctl() and suid_dumpable (CVE-2006-2451)
During security research, Red Hat discovered a behavioral flaw in core
dump handling. A local user could create a program that would cause a
core file to be dumped into a directory they would not normally have
permissions to write to. This could lead to a denial of service (disk
consumption), or allow the local user to gain root privileges.
--- linux-2.6.9/kernel/sys.c.orig
+++ linux-2.6.9/kernel/sys.c
@@ -1702,7 +1702,7 @@ asmlinkage long sys_prctl(int option, un
error = 1;
break;
case PR_SET_DUMPABLE:
- if (arg2 < 0 || arg2 > 2) {
+ if (arg2 < 0 || arg2 > 1) {
error = -EINVAL;
break;
}
*** Bug 137627 has been marked as a duplicate of this bug. ***
Dan; please add to genpatches and commit new gentoo-sources as soon as
possible. Thanks.
*** Bug 139668 has been marked as a duplicate of this bug. ***
Please bump vanilla-sources to 2.6.17.4, which fixes this problem.
Proof of Concept can be found here:
http://www.rs-labs.com/exploitsntools/rs_prctl_kernel.c
I've tryed it, but it doesn't works for me:
user@host ~ $ ./rs_prctl_kernel
Linux Kernel 2.6.x PRCTL Core Dump Handling - Local r00t
By: dreyer & RoMaNSoFt
[ 10.Jul.2006 ]
[*] Creating Cron entry
[*] Sleeping for aprox. one minute (** please wait **)
[*] Running shell (remember to remove /tmp/sh when finished) ...
sh: /tmp/sh: No such file or directory
user@host ~ $ uname -a
Linux linux 2.6.16-gentoo-r7 #2 Mon May 22 14:19:25 MSD 2006 i686 Pentium Pro
GNU/Linux
I was pointed out that this exploit acctually may create /tmp/sh more 1 minute.
So I've modified sleep() time in exploit to 3 minutes. It creates suid root
/tmp/sh:
nstorm@linux ~ $ ./rs_prctl_kernel
Linux Kernel 2.6.x PRCTL Core Dump Handling - Local r00t
By: dreyer & RoMaNSoFt
[ 10.Jul.2006 ]
[*] Creating Cron entry
[*] Sleeping for aprox. sleep(180) (** please wait **)
[*] Running shell (remember to remove /tmp/sh when finished) ...
sh-3.1$ ls -l /tmp/sh
-rwsr-xr-x 1 root root 659552 Jul 12 13:19 /tmp/sh
Fromm looking at the patch I changed
- prctl(PR_SET_DUMPABLE, 2);
+ prctl(PR_SET_DUMPABLE, 3);
Then it works, unfortunately:
./pop
Linux Kernel 2.6.x PRCTL Core Dump Handling - Local r00t
By: dreyer & RoMaNSoFt
[ 10.Jul.2006 ]
[*] Creating Cron entry
[*] Sleeping for aprox. one minute (** please wait **)
[*] Running shell (remember to remove /tmp/sh when finished) ...
$sh-3.1$ ls -l /tmp/sh
-rwsr-xr-x 1 root root 632016 12. Jul 11:21 /tmp/sh
:((
This is freaky. There is obviously something seriously wrong. The code is
supposed to back out if the parameter is invalid, right? So the patch won't
work at all, IMHO :(
(In reply to comment #8)
> This is freaky. There is obviously something seriously wrong. The code is
> supposed to back out if the parameter is invalid, right? So the patch won't
> work at all, IMHO :(
You need to upgrade to the new kernel which is actually patched against this
vulnerability :)
We were actually trying to mark this as valid, I believe :D
And it is, obviously.
That patch is not a real fix unless prctl(PR_SET_DUMPABLE, 2) isn't expected to
work anymore. In that case manpages should be updated.
Otherwise a better fix maintaining functionality would be to dump core on user
writable directories only.
A temporary workaround to the local root escalation is to chmod o-rx
/etc/cron.d - This prevents the program from calling chdir("/etc/cron.d"), thus
preventing the core file from being dumped there, and so on. I'm sure there are
other ways this kernel bug could be exploited, but at least this prevents root
escalations from the method described in the example.
Does anybody know if PR_SET_DUMPABLE,2 is going to be supported in the future
(since it's quite a new feature so it possibly just got pulled in order to
hotfix it)?
(In reply to comment #11)
> That patch is not a real fix unless prctl(PR_SET_DUMPABLE, 2) isn't expected to
> work anymore. In that case manpages should be updated.
The manpages never said anything other than zero or one should ever work. At
least the one I'm looking at here dated 2002-06-27, anyway. The issue was that
the check didn't enforce this correctly due to an off-by-one and hence the bug.
Huh? From man-pages-2.34:
PR_SET_DUMPABLE
[...]
Since kernel 2.6.13, the value 2 is also permitted; this causes any
binary which normally would not be dumped to be dumped readable by
root only. (See also the description of /proc/sys/fs/suid_dumpable in
proc(5).)
*** Bug 140303 has been marked as a duplicate of this bug. ***
Whatever, new versions don't exhibit the problem.
CCing maintainers; please bump:
mips-sources: Kumba
rsbac-sources: kang
sh-sources: sh
usermode-sources: dang
xbox-sources: chrb
xen-sources: chrb, agriffis
(In reply to comment #18)
> CCing maintainers; please bump:
>
> mips-sources: Kumba
> rsbac-sources: kang
> sh-sources: sh
> usermode-sources: dang
> xbox-sources: chrb
> xen-sources: chrb, agriffis
>
you guys might want to use genpatches-2.6.16-15 instead of -14, because it
addresses bug 140444 as well...
Tested patch by reporter on vanilla, works fine.
Just to make this clear:
+ prctl(PR_SET_DUMPABLE, 3);
in the exploit code as written in comment #7 does not work to exploit a patched
kernel! Caused quite some FUD to me so I checked.
Two things just out of interest and then I'll shut up:
< 2.6.13 is not exploitable from what the "case PR_SET_DUMPABLE" looks like in
sys.c
(securityfocus appears to be wrong on their
The 2.4.x branch doesn't appear to be vulnerable to this either - same
if (arg2 != 0 && arg2 != 1) like 2.6.12
usermode-sources bumped to -15
(In reply to comment #12)
> A temporary workaround to the local root escalation is to chmod o-rx
> /etc/cron.d - This prevents the program from calling chdir("/etc/cron.d"),
Well, this obviously doesn't help much. It just prevents this particular
exploit from executing, but if you can write files in that way, there's a bunch
of other ways for breaking root.
Anothere, not much better, "workaround" is to specify the core dump location:
echo /root/core > /proc/sys/kernel/core_pattern
(you create a denial of service possibility then)
Or put a limit:
in /etc/limits.conf
* hard core 0
Or set it to /dev/null ... you can use fantasy.
Another temporary workaround for those who cannot update a system right now for
whatever reason is to load the LKM I upload... please beware, it comes straight
from an infosec list, so usual precautions against unofficial patches apply.