December 13, 2006
This article was contributed by Jake Edge.
When a security bug is found in the kernel, a patch is usually available
within hours; the kernel developers rightly take these things very seriously.
Once the patch is available, the stable team typically releases a new kernel
within a week or so and this is one of the big advantages of open source.
Once in a while, however, a bug that has been fixed previously can creep
back into the source, open or closed, and is known as a 'regression'.
This week's 2.6.19.1 kernel
release has a fix for something
that looks an awful lot like a regression, but technically is not.
Back in July, LWN described
a security problem in the then-current 2.6.17 kernel. The issue was that
local users could configure their processes to write core dump files in
directories that they did not have write permissions for. As the article
described, this could be trivially exploited for local privilege escalation;
in short, a local root hole.
This bug was fixed by the following patch:
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1983,7 +1983,7 @@ asmlinkage long sys_prctl(int option, un
error = current->mm->dumpable;
break;
case PR_SET_DUMPABLE:
- if (arg2 < 0 || arg2 > 2) {
+ if (arg2 < 0 || arg2 > 1) {
error = -EINVAL;
break;
}
which prevented processes from setting the
dumpable flag to two. That flag
governs whether core dumps are produced by the process; the special
value of two reflects an ability to dump core with root privileges, quite
possibly to directories that the user cannot normally write to. The code
did guard against overwriting existing files, for security reasons, but
did not consider the implications of allowing user processes to effectively
write anywhere.
The code which handles the dumpable flag lives in fs/exec.c in the
aptly named do_coredump() function:
if (mm->dumpable == 2) { /* Setuid core dump mode */
flag = O_EXCL; /* Stop rewrite attacks */
current->fsuid = 0; /* Dump root private */
}
and further down, flag is used as part of the filp_open()
call:
file = filp_open(corename, O_CREAT|2|O_NOFOLLOW|O_LARGEFILE|flag, 0600);
At the end of September, a
patch by Andi Kleen was
applied to allow core dumps to be piped to a userspace process. This
patch had been, according to Andi, "hanging around for a long time" and
lacked the flag
in the call to filp_open(). The patch made it into 2.6.19-rc1
kernel and from there into 2.6.19.
The impact of the bug is relatively low as a root user would have to set
the dumpable flag to two via
/proc/sys/fs/suid_dumpable. This would allow user processes to write
core dumps anywhere, which is as designed, but also would allow them to
overwrite existing files, which is not. It probably is not very common
that admins need to configure things that way, but it certainly is not
completely outside the realm of possibility either.
As described in the patch, Alexey Dobriyan
used a list of warnings
gathered from compiling the kernel. The warnings were grepped for
'was set but never used' and the first entry in the list pointed to this
problem. The kernel produces enough warnings that problems like this tend
to be obscured in a sea of bogus or overly picky warnings.
This particular bug is not technically a regression as there never was a bug
that allowed this behavior until it was introduced in the patch. It has been
assigned
CVE-2006-6304
(as of this writing, it is just a reserved CVE with no information).
It is great to see folks scrutinizing warnings and looking for bugs in the
kernel, this is just the kind of thing that the 'many eyes make all bugs
shallow' theory is referring to.
It would be nice to see a kernel regression test suite that contained
test cases for bugs that have previously been fixed as that kind of thing
might have caught this bug. It is a difficult problem, however, and keeping
up with the number of bug fix patches would be daunting. Perhaps a regression
suite that focused on security fixes would be a good place to start.
(
Log in to post comments)