LWN.net Logo

Another kernel core dump security issue

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)

Another kernel core dump security issue

Posted Dec 14, 2006 15:22 UTC (Thu) by beejaybee (guest, #1581) [Link]

When is a core dump _not_ a security issue?

I mean, if it is possible to dump the kernel at all, surely it is at least theoretically possible to mount the file system with a different OS and pull the dump file apart - thereby possibly disclosing the memory of every process running at the time the core dump was executed.

Have I got the wrong end of the stick here?

BTW I do know that core dumps are near essential in a development environment!

Another kernel core dump security issue

Posted Dec 14, 2006 16:14 UTC (Thu) by pflugstad (subscriber, #224) [Link]

Um, I think in this context core_dump refers to the core of the APPLICATION process, not the kernel., and I don't think any kernel data structures are included in this.

Another kernel core dump security issue

Posted Dec 19, 2006 5:08 UTC (Tue) by roelofs (guest, #2599) [Link]

That was my interpretation, too. I believe the kernel kind is more commonly referred to as a "crash dump."

Greg

Another kernel core dump security issue

Posted Dec 14, 2006 22:04 UTC (Thu) by Frej (subscriber, #4165) [Link]

What if warnings where shown when while the code?
1) Wrong warnings would get removed faster (Since they are more annoying?)

2) Warnings that matter would actually be read at the time code is written

Complex yes, but should be possible given enough time ;)

regression or not

Posted Dec 16, 2006 1:11 UTC (Sat) by giraffedata (subscriber, #1954) [Link]

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.

The technical definition of regression doesn't require a formerly existing bug. A regression is a case where Release N+1 is worse than Release N. From the latin meaning, "to step backward." In most contexts, the definition is narrowed to: Something that works in Release N does not in Release N+1.

Regressions are separated from other bugs because a regression is a reason not to upgrade to N+1, whereas other bugs are not.

In this case, it's hard to cast the bug in any light in which it is not a regression. 2.6.18 is secure from hackers; 2.6.19 is not. A step backward. A reason to regret going to 2.6.19.

I've also heard of code regression, which might be more applicable here. That's where you accidentally overwrite new code with old code, which happens if multiple simultaneous developers aren't careful. A cursory glance it this bug might give you the impression is was caused by a code regression.

regression or not

Posted Dec 16, 2006 2:42 UTC (Sat) by bronson (subscriber, #4806) [Link]

Do you have a link to your "technical definition of regression?" I've worked for a number of companies where a regression simply means hunting for a bug that had been closed and re-opening it. Regression testing is testing closed bugs to see if they've been re-introduced. Since it's mostly QA, determining if a bug is a regression or not certainly does not require intimate knowledge of the code.

Unless you have some formal standard supporting your position, I'd suggest being a little less authoritative on the matter?

regression or not

Posted Dec 16, 2006 4:02 UTC (Sat) by giraffedata (subscriber, #1954) [Link]

I speak with authority on things of which I am completely certain that I know what I'm talking about. In the unlikely event that someone challenges me, I can then supply better authority or just let the challenge stand as a correction of that authority.

I am in fact surprised to hear that you heard regression and regression testing used that way, which is even weirder (hunting for a bug?) than the way it's used in the article. I guess there's more abuse of the term out there than I knew.

The best authority I can give is the definition of "regression" in an English dictionary. Software engineers don't pull words at random from the dictionary to describe their processes; they use words whose regular usage describes the process. The English "regression" doesn't fit hunting for old bugs or reintroduction of old bugs specifically. But it does describe quite nicely breaking something that used to work.

I also typed "regression testing" into Google and the first two results were dictionaries - Webopedia and Wikipedia - that defined it quite well in a way inconsistent with the definition used in the article and in your comment. The Webopedia one has an error in that in one place it suggests ALL testing of code is regression testing, but the Wikipedia is quite good. Definition of regression is implicit in the definition of regression testing.

My guess is if you looked at the next 50 Google results, at least 45 of them would use regression in a way inconsistent with limiting it to reintroduction of old bugs. I can say this because I've seen the term used in dozens of projects, and it's nearly always the same way, consistent with the plain English "regression."

I can't believe you worked somewhere where regression tests included only tests related to previously reported bugs. What about all the test cases that were written for new features in past releases? Didn't you rerun those too every time you changed code (and call it regression testing)?

Until now, the only abuse of "regression testing" I've seen is that some people think it means automated testing. That's because regression testing is virtually always automated, as a practical necessity, while new function testing often isn't.

regression or not

Posted Dec 19, 2006 5:20 UTC (Tue) by roelofs (guest, #2599) [Link]

What about all the test cases that were written for new features in past releases?

I believe those are more commonly referred to as unit tests. They may or may not be run as part of automated regression testing; I've seen it handled both ways. They're often at a far lower (and less interesting) level than "real" regression test cases, which, in my experience, are designed to call attention to ambiguous changes in behavior--"Is that expected/intended from the recent code changes, or did somebody break something while fixing/improving/adding something else?"

To put it another way, the practical distinction (often) is that unit tests are at the component level, while regression tests are at the system level. YMMV, of course.

Greg

regression or not

Posted Dec 19, 2006 16:59 UTC (Tue) by giraffedata (subscriber, #1954) [Link]

Well, I'll take your word for how "unit test" is commonly used, because I hardly ever see it. But I know that what it's supposed to mean (what it meant when coined and makes logical sense) has nothing to do with what we've been discussing.

The place I've most seen "unit test" used is IBM software development, where it was shamelessly abused to mean "testing done by the coding department, as opposed to the testing department."

Its original meaning, which, like "regression testing," you need only go to an English dictionary to understand, is testing of individual units of development as opposed to the entire product. According to my old software engineering textbook, it typically means testing a single module of code, which you do by building scaffolding for that module and possibly injecting inputs and examining outputs with debugging tools. After the unit tests are all complete, you move on to system testing. I think unit testing is rare these days because it's cheaper to build and run an entire system as your test driver than to construct single-module test drivers.

And thus, unit vs system testing is orthogonal to regression vs progression testing. If you run a test case that calls kmalloc() to make sure the new GFP_FOO kmalloc flag does what it's supposed to, that's a progression unit test. When you rerun that same test after adding GFP_BAR code to make sure you didn't break GFP_FOO, that's a regression unit test. If you just bring up Fedora, with the new kmalloc code, and browse the web for a while and verify memory doesn't leak, that's a system test, either regression or progression.

Copyright © 2006, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds