A /proc/PID/mem vulnerability
A privilege escalation in the kernel is always a serious threat that leads kernel hackers and distributions to scramble to close the hole quickly. That's exactly what happened after a January 17 report from Jüri Aedla to the closed kernel security mailing list. But most people didn't learn of the hole from Aedla (since he posted to a closed list), but instead from Jason Donenfeld (aka zx2c4) who posted a detailed look at the flaw on January 22. The fix was made by Linus Torvalds and went into the mainline on January 17, though with a commit message that obfuscated the security implications—something that didn't sit well with some.
The problem and exploit
The problem itself stems from the removal of the restriction on writes to /proc/PID/mem that was merged for the 2.6.39 kernel. It was part of a patch set that was specifically targeted at allowing debuggers to write to the memory of processes easily via the /proc/PID/mem file. Unfortunately, it left open a hole that Aedla and Donenfeld (at least) were able to exploit.
The posting by Donenfeld is worth a read for those interested in how exploits of this sort are created. The problem starts with the fact that the open() call for /proc/PID/mem does no additional checking beyond the normal VFS permissions before returning a file descriptor. That will prove to be a mistake, and one that Torvalds's fix remedies. Instead of checks at open() time, the code would check in write() and only allow writing if the process being written to is the same as the process doing the writing (i.e. task == current).
That restriction seems like it would make an exploit difficult, but it can be avoided with an exec() and coercing the newly run program to do the writing to itself. That will be dangerous if the newly run program is a setuid executable for example. But there is another test that is meant to block that particular path, by testing that current->self_exec_id has the same value as it did at open() time. self_exec_id is incremented every time that a process does an exec(), so it will definitely be different after executing the setuid binary. But, since it is simply incremented, one can arrange (via fork()) to have a child process with the same self_exec_id as the main process after the setuid exec() is done.
The child with the "correct" self_exec_id value (which it gets by doing an exec()) can then open the parent's /proc/PID/mem file (since there are no extra checks on the open()) and pass the descriptor back to the parent via Unix sockets. The parent then needs to arrange that the setuid executable writes to that file descriptor once a seek() to the proper address has been done. Finding that proper address and getting the binary to write to the fd are the final pieces of the puzzle.
Donenfeld's example uses su because it is not compiled as a position-independent executable (PIE) for most distributions, which makes it easier to figure out which address to use. He exploits the fact that su prints an error message when it is passed an unknown username and the error message helpfully prints the username passed. That allows the exploit to pass shellcode (i.e. binary machine language that spawns a shell when executed) as the argument to su.
After printing the error message, su calls the exit() function (really exit@plt), which is what Donenfeld's exploit overwrites. It finds the address of the function using objdump, subtracts the length of the error message that gets printed before the argument, and seeks the file to that location. It uses dup2() to connect stderr to the /proc/PID/mem file descriptor and execs su "shellcode".
In pseudocode, it might look something like this:
if (!child && fork()) { /* child flag set based on -c */ /* first program invocation, this is parent, wait for fd from child */ fd = recv_fd(); /* get the fd from the child */ dup2(2, 15); dup2(fd, 2); /* make fd be stderr */ lseek(fd, offset); /* offset to overwrite location */ exec("/bin/su", shellcode); /* will have self_exec_id == 1 */ } else if (!child) { /* this is the child from the fork(), exec with child flag */ exec("thisprog", "-c"); /* this program with -c (child) */ } else { /* child after exec, will have self_exec_id == 1 */ fd = open("/proc/PPID/mem", O_RDWR); /* open parent PID's mem file */ send_fd(fd); /* send the fd to the parent */ }Of course Aedla's proof-of-concept or Donenfeld's exploit code are likely to be even more instructive.
It's obviously a complicated multi-step process, but it is also a completely reliable way to get root privileges. Updates to Donenfeld's post show exploits for distributions like Fedora that do build su as a PIE, or for Gentoo where the read permissions on setuid binaries have been removed so objdump can't be used to find the address of the exit function. For Fedora, gpasswd can be substituted as it is not built as a PIE, while on Gentoo, ptrace() can be used to find the needed address. While it was believed that address space layout randomization (ASLR) for PIEs would make exploitation much more difficult, that proved to be only a small hurdle, at least on 32-bit systems.
The fix and reactions
The fix hit the mainline without any coordination with Linux
distributions. Kees Cook, who works on ChromeOS security (and
formerly was a member of the Ubuntu security team), told LWN that Red Hat has a person on the closed
kernel security mailing list, so it was aware of the problem but did not
share that information on the Linux distribution security list. "I've been told this will
change in the future, but I'm worried it will be overlooked again
",
he said. The first indication that
other distributions had was likely from Red Hat's Eugene Teo's request for a CVE on the
oss-security mailing list.
As Cook points out, the abrupt public disclosure of the bug (via a mainline commit) runs counter to the policy described in the kernel's Documentation/SecurityBugs file, where the default policy is to leave roughly seven days between reports to the mailing list and public disclosure to allow time for vendors to fix the problem. Cook is concerned that bugs reported to security@kernel.org are not being handled reasonably:
The "just a bug" refers to statements that Torvalds has made over the years about security bugs being no different than any other kind of bug. In email, Torvalds described it this way:
In keeping with that philosophy, Torvalds does not disclose the security
relevance of a fix in the commit message: "I think the whole 'mark this patch as having security implications' is
pure and utter garbage
". Even if there is a known security problem
that is being fixed, his commit
messages do not reflect that, as with the message for the
/proc/PID/mem fix:
This changes it to do the permission checks at open time, and instead of tracking the process, it tracks the VM at the time of the open. That simplifies the code a lot, but does mean that if you hold the file descriptor open over an execve(), you'll continue to read from the _old_ VM.
Torvalds's commit message stands in pretty stark contrast to Aedla's report to security@kernel.org (linked above):
This "masking" of the actual reason for a commit doesn't sit well with
either Cook or Teo (who also responded to an email query). Cook "cannot overstate how much I am
against this kind of masking
", while Teo pointed out that this
particular bug is in no way unique:
Both Teo and Cook were in agreement that disclosing what is known about a fix at the time it is applied can only help distributions and others trying to track kernel development. Torvalds, on the other hand, is concerned about attackers reading commit messages, which could lead to more attacks against Linux systems. He has a well-known contempt for security "clowns" that seems to also factor into his reasoning:
Both the security camps hate me. The full disclosure people think I try to hide things (which is true), while the embargo people think I despise their corrupt arses (which is also true).
The strange thing is that by explicitly not putting the known security implications of a patch into the commit message, Torvalds is treating security bugs differently. They are no longer "just bugs" because some of the details of the bug are being purposely omitted. That may make it difficult for "black hats"—though it would be somewhat surprising if it did—but it definitely makes it more difficult for those who are trying to keep Linux users secure. Worse yet, it makes it more difficult down the road when someone is looking at a commit (or reversion) in isolation because they may miss out on some important context.
Silent security fixes are a hallmark of proprietary software, and Torvalds's policy resembles that to some extent. It could be argued (and presumably would be by Torvalds and others) that the fixes aren't silent since they go into a public repository and that is true—as far as it goes. By deliberately omitting important information about the bug, which is not done for most or all other bugs, perhaps they aren't so much silent as they are "muted" or, sadly, "covered up". There is definitely a lot of validity to Torvalds's complaints about the security "circus", but his reaction to that circus may not be in the best interests of the kernel community either.
Index entries for this article | |
---|---|
Kernel | Security/Vulnerabilities |
Security | Linux kernel |
Security | Vulnerabilities/Privilege escalation |
(Log in to post comments)
Editorial section?
Posted Jan 25, 2012 23:37 UTC (Wed) by nevets (subscriber, #11875) [Link]
By deliberately omitting important information about the bug, which is not done for most or all other bugs, perhaps they aren't so much silent as they are "muted" or, sadly, "covered up". There is definitely a lot of validity to Torvalds's complaints about the security "circus", but his reaction to that circus may not be in the best interests of the kernel community either.
Jake, this article has a bit more "opinion" in it than just the facts. It almost sounds like this is a sore topic for you.
Editorial section?
Posted Jan 25, 2012 23:56 UTC (Wed) by raven667 (subscriber, #5198) [Link]
Editorial section?
Posted Jan 26, 2012 0:09 UTC (Thu) by nevets (subscriber, #11875) [Link]
Seriously though, I didn't look at the author of the article as I read it. As I was more than half way down, I was thinking "hmm, this has the sound of Jake's opinions", and then I scrolled back up, and sure enough it was him.
Editorial section?
Posted Jan 26, 2012 0:13 UTC (Thu) by PaXTeam (guest, #24616) [Link]
Editorial section?
Posted Jan 26, 2012 0:42 UTC (Thu) by nevets (subscriber, #11875) [Link]
He mentioned this as a bug fix, not a security fix. Does he really need to specify "this fixes a privilege escalation vulnerability"? Some say yes, some say no, but both choices are *opinions*!
Actually, what was left out of the article is more damning to Torvalds than what was in the article. I just read the full commit log, and if anything, this part I would consider the most incriminating against him:
"If somebody actually finds a load where this matters, we'll need to revert this commit"
One would not want to revert a commit that is a security fix. And even Linus stated that once.
I'm friends with Jake, and have had many a beer with him discussing lots of topics. As I read this article, I could hear his opinion slipping into what he wrote. Maybe, it's just me. Jake's a good guy, but he also human (that's a strike against us all). I was just stating that this article seemed to have a little more opinion in it than in other articles.
Still, I find Jake's writing superb.
Editorial section?
Posted Jan 26, 2012 1:12 UTC (Thu) by PaXTeam (guest, #24616) [Link]
that's easy to answer. using your example, you're saying that it is a matter of opinion whether a security fix says 'security fix' or just 'fix'. by that logic it is also a matter of opinion whether a filesystem corruption fix simply says 'filesystem corruption fix' or 'fix'. we know from existing commits that this opinion thing favours the first kind of description for filesystem corruptions. why does the same opinion favour the second kind then for security fixes? isn't a bug a bug after all? and let's not forget that security bugs (e.g., memory corruption ones) can very well cause filesystem corruption, one would think that they would at least be described as such in the commit, but not even that happens. inquiring minds would like to know the reason for these seemingly inconsequential decisions ;).
> One would not want to revert a commit that is a security fix.
i don't think he said everything he wanted to. my guess is that he would have continued with '...and fix it another way' but that would have given away even more hints as to the severity of the situation (it would have shown that one way or another, something really truly must be done here whereas a casual 'we will revert if needed' will make the less observative reader think that 'ok, nothing really important is going on here, at most i will see a revert in the coming days').
Editorial section?
Posted Jan 26, 2012 1:26 UTC (Thu) by nevets (subscriber, #11875) [Link]
If somebody actually finds a load where this matters, we'll need to revert this commit
I'm surprised someone didn't respond to this saying:
"Hey! My rootkit no longer works. Please revert this commit."
Editorial section?
Posted Jan 26, 2012 17:30 UTC (Thu) by nix (subscriber, #2304) [Link]
(I pointed out how stunningly unwise this was, and was told that this was the way they'd always done it and they weren't going to change.)
Editorial section?
Posted Jan 26, 2012 0:30 UTC (Thu) by jake (editor, #205) [Link]
I think it is not uncommon for our articles to offer an opinion, so long as it's clearly separated from the factual part. I think this is. And, no, I'm not at all comfortable with seeing information on bugs covered up. I can't really see any upside at all.
jake
Editorial section?
Posted Jan 26, 2012 0:45 UTC (Thu) by nevets (subscriber, #11875) [Link]
We'll have to discuss it over a beer at ELC in a few weeks ;-)
Editorial section?
Posted Jan 26, 2012 16:07 UTC (Thu) by emk (subscriber, #1128) [Link]
Please keep up the good work. :-)
Editorial section?
Posted Feb 1, 2012 23:01 UTC (Wed) by liljencrantz (guest, #28458) [Link]
Remaining completely neutral in situations where you have a strong opinion is (in my opinion) impossible, but I urge you to keep trying.
A /proc/PID/mem vulnerability
Posted Jan 26, 2012 0:29 UTC (Thu) by PaXTeam (guest, #24616) [Link]
the open permission checks play no role here because /prod/pid/mem is opened *before* the suid execve, therefore the given process has every right to do it by design. the real problem is that the open gives access to an object (mm_struct) that is then *replaced* by the execve and the read/write accessors used the new object (that open can't have seen and denied access to). in other words there was an underlying assumption (fd = content) that wasn't true and the fix ensures this assumption now.
A /proc/PID/mem vulnerability
Posted Jan 26, 2012 7:07 UTC (Thu) by kurtseifried (guest, #57307) [Link]
-----
Your article has a major error (well several but this is one of the
biggest):
"The first indication that other distributions had was likely from Red
Hat's Eugene Teo's request for a CVE on the oss-security mailing list."
Sigh. No. This issue was discussed on the vendor sec list (a list
specifically created for Linux distribution security people so they can
notify each other of embargoed issues and co-ordinate things, share
fixes, workarounds, etc.) and all the main Linux distributions (well
anyone that cares enough about security to have a security person sign
up for the vendor-sec list) knew about this issue in advance of the
public CVE request to OSS-sec.
For more information on the closed list please see:
http://seclists.org/oss-sec/2011/q2/4
if you go through the archives (look for subject line "Closed list" or
"Re: Closed list" and you'll find pretty much every major Linux vendor
is on there.
Kurt Seifried / Red Hat Security Response team
A /proc/PID/mem vulnerability
Posted Jan 26, 2012 8:53 UTC (Thu) by danielpf (guest, #4723) [Link]
A /proc/PID/mem vulnerability
Posted Jan 31, 2012 5:45 UTC (Tue) by malor (guest, #2973) [Link]
and commenting bugs too early damages Linux security reputation.A better summation would be tells the truth, and we can't have users knowing the TRUTH, because they might not use Linux.
Much, much better to lie to them, to get users to use your code.
Well, better for you, anyway.
A /proc/PID/mem vulnerability
Posted Jan 31, 2012 5:48 UTC (Tue) by malor (guest, #2973) [Link]
I mean, that's the Catholic Church approach to computer security -- the reputation of the
A /proc/PID/mem vulnerability
Posted Jan 26, 2012 11:24 UTC (Thu) by PaXTeam (guest, #24616) [Link]
does it? let's see the timeline:
1. original bugreport: Tue, 17 Jan 2012 07:38:51 +0200
2. Linus' commit: Tue, 17 Jan 2012 23:21:19 +0000 (15:21 -0800)
3. Eugene's mail on oss-sec: Wed, 18 Jan 2012 10:25:55 +0800
4. CVE assigned by Kurt: Tue, 17 Jan 2012 19:30:33 -0700
5. Red Hat bugzilla #782681: 2012-01-18 02:09:22 EST
6. Fedora fix by Josh Boyer: Wed, 18 Jan 2012 15:08:53 +0000 (10:08 -0500)
7. Kees' mail on oss-sec: Wed, 18 Jan 2012 12:43:28 -0800
8. Kees' mail on the 'secret' vendor list: Thu, 19 Jan 2012 00:06:50 -0800
you're saying that something else happened between 2 and 3 on linux-distros? evidence wants to be seen! i'm also wondering how Eugene had gotten wind of the security related impact of the commit before anyone else did.
A /proc/PID/mem vulnerability
Posted Jan 26, 2012 10:28 UTC (Thu) by rswarbrick (guest, #47560) [Link]
... Torvalds is treating security bugs differently. They are no longer "just bugs" because some of the details of the bug are being purposely omitted. That may make it difficult for "black hats"—though it would be somewhat surprising if it did—but it definitely makes it more difficult for those who are trying to keep Linux users secure.
Well, kernels are more painful to upgrade than most other software (since you pretty much have to reboot). As such, there's always going to be a bigger window between patches going out and machines being patched. If someone is malicious and knows about what's going on in advance, you're stuffed whatever Linus chooses to write in the commit message.
However, if someone malicious is grepping through kernel commits for "suid", "privilege escalation" or the like, it doesn't make much sense to point out bugs for them. There are a *lot* of patches going into the kernel each day: without a "OOH LOOK, THIS IS FOR HAXXORS" message, I find it hard to believe that staring at kernel commits is a good way to find vulnerabilities.
A /proc/PID/mem vulnerability
Posted Jan 26, 2012 14:11 UTC (Thu) by PaXTeam (guest, #24616) [Link]
> (since you pretty much have to reboot).
well, there is ksplice...
> If someone is malicious and knows about what's going on in advance,
> you're stuffed whatever Linus chooses to write in the commit message.
blackhats don't work based off the fix, they work based on the original commit that *introduces* the bug, weeks/months/years before the fix happens (if it happens at all, there's always 0-day out there). and for the people who do work based off the fix, this very bug and its fix is proof that no amount of coverup helps: there're already at least 4 public and 2 private exploits out there for it that i know of. what was the point of the coverup then? it most definitely failed to achieve the goal of "try not to help black hats".
> There are a *lot* of patches going into the kernel each day: without
> a "OOH LOOK, THIS IS FOR HAXXORS" message
at this point *any* commit from Linus directly referencing a non-public message is an immediate red flag. he has achieved the exact opposite he wished for.
> [...]I find it hard to believe that staring at kernel commits is a good way to find vulnerabilities.
(un)fortunately, blackhats don't share your belief. remember http://seclists.org/fulldisclosure/2010/Sep/268 ?
A /proc/PID/mem vulnerability
Posted Jan 26, 2012 20:06 UTC (Thu) by vonbrand (guest, #4458) [Link]
Oh, come on. "There is a exploit out for a widely-discussed security bug" is not the same as "there is an expoit out there for each and every security bug." As long as you can't reasonably know if to publish any hint of possible security impact or just keep it quiet is the better course of action.
A /proc/PID/mem vulnerability
Posted Jan 26, 2012 22:34 UTC (Thu) by PaXTeam (guest, #24616) [Link]
> same as "there is an expoit out there for each and every security bug."
strawman and also an irrelevant tautology.
> As long as you can't reasonably know if to publish any hint of possible
> security impact or just keep it quiet is the better course of action.
real life says that you can reasonably know that there's an entire industry, both visible and invisible, out there that is watching and writing exploits as soon as they can get their hands on a bug, be that at bug commit time or later (the sooner the better as the value of 0-day beats anything else).
on the other hand the best course of action for users of said buggy code to save themselves is to fix the bugs (yes, i'm stating this myself despite being deeply involved in intrusion prevention technologies). for that they need to know about them, simple as that. covering up security fixes is diametrically opposite to that goal as it makes it much harder for users to reverse engineer the information from the commits whereas said industry has the brainpower to see through these silly attempts (as i said above, commits from Linus and certain other individuals draw immediate attention these days, witness what happened to this /proc/pid/mem bug).
btw, if you think keeping quiet about security impact information is the right course of action, what do you think about companies (linux vendors included) who do exactly that?
PS: i'm glad you stopped doubting that there *is* a coverup. you've come a long a way ;).
A /proc/PID/mem vulnerability
Posted Jan 26, 2012 23:01 UTC (Thu) by PaXTeam (guest, #24616) [Link]
err, i obviously meant 'who do exactly the opposite' ;).
A /proc/PID/mem vulnerability
Posted Jan 26, 2012 14:47 UTC (Thu) by ortalo (guest, #4654) [Link]
Outside of that situation, it seems (to me) to be a little pointless because focussed on a too small perimeter.
First I think at least as much, and possibly more energy should be spent on preventing the introduction of vulnerabilities than on setting up infrastructure or procedures for correcting them. For example, more talking on coding practices, auditing techniques, architectures with several layers of proection or the associated tools that prevent the introduction of bugs with a security impact; than on how to acquire/propagate the information concerning vulnerabilities. In short: work not to introduce vulnerabilities as much as removing them.
Furthermore, the information needed by an attacker is not necessarily the same as the information needed by a security officer, so the content of the disclosure information should be taken into account in the debate. But there is certainly little ROI to expect from this additional effort on writing vulnerability notes, esp. given the previous point.
Finally, the actual impact of full disclosure or embargo depends on the final security needs of a specific system: at home, maybe I am not so much impacted, at work on a highly valuable system, maybe I am. Or maybe the opposite, because the involved software is used at home and not at work. So, trying to get a definitive answer on the best procedure is most certainly impossible in the general case. Fortunately, there are many other things to do.
A missed point
Posted Jan 27, 2012 23:59 UTC (Fri) by zlynx (guest, #2285) [Link]
Therefore, if you are relying on commit messages to have a big "Security Fix Here" tag so that you know when to upgrade your kernel, you will be insecure anyway.
A missed point
Posted Jan 28, 2012 0:50 UTC (Sat) by neilbrown (subscriber, #359) [Link]
As a general rule, many commit messages are not as informative as they could be or should be. Andrew Morton regularly rants about this. I personally find that writing a good commit message helps me find problems with the commit often enough that it is clearly worth while. It seems that others don't :-(
So commit messages don't guarantee anything, and they could certainly be better.
But that doesn't excuse removing security related information from commit messages, or deliberately leaving it out. We should always include anything useful that we know. We cannot justify leaving info out because some other commit message doesn't have that kind of info.
So sure: if people only back-port commits which say "bug fix" or "security issue" in the commit message, then they are being foolish. But it is not our place (or Linus' place) to stop people from being foolish.
It *is* our place to make the code and the code-history as easy to understand and maintain as possible.
A missed point
Posted Jan 28, 2012 0:54 UTC (Sat) by PaXTeam (guest, #24616) [Link]
A missed point
Posted Feb 9, 2012 11:45 UTC (Thu) by kevinm (guest, #69913) [Link]
A /proc/PID/mem vulnerability
Posted Jan 30, 2012 9:43 UTC (Mon) by alonz (subscriber, #815) [Link]
What's really sad is that the exact same vulnerability was already known when the “fix” to relax the permissions was made (see references in this linux-kernel message from Alan Cox). Had the issue been clearly documented in comments / changelog messages, and not just on the mailing list, it would not have been lost.
And now the new patch is in place, and again the security implications are not documented where they will be seen by future developers. So we can certainly expect someone to “fix” break this again one day, just because critical information was withheld from the changelog.
A /proc/PID/mem vulnerability
Posted Feb 8, 2012 7:41 UTC (Wed) by Duncan (guest, #6647) [Link]
What is there about ...
"isn't very robust.. doesn't match the permission checking... This changes ... permission checks"
... that does not SCREAM security vuln? To me it certainly does!
I mean, what is one /doing/ "permissions checks" for if not for security? Otherwise they'd be something else, data validity checks, maybe. But if they're permissions checks, then by implications there's something there to be secured BY those permissions checks.
And if the simple phrase "permission checks" isn't enough to get someone investigating, surely adding "isn't very robust... changing" to the mix, when the context is "permission checks" should do so!
If I say my bank account isn't very robust and that I'm working to change it, who wouldn't read that as a saying I lack money but am trying to change it? If I say the permission checks aren't very robust and that they're being changed, how on earth can it mean anything BUT "THIS COMMIT HAS POTENTIAL SECURITY IMPLICATIONS!"? (Yes, to me it's SHOUTING, so the caps are warranted.)
Duncan
A /proc/PID/mem vulnerability
Posted Feb 11, 2012 19:56 UTC (Sat) by alonz (subscriber, #815) [Link]
Yes, the changelog doesn't competently hide that there are security issues.But it does hide the specific vulnerability in the previous code. So it's really useless for educating the next generation. (Unless you believe whoever next touches this code will magically understand what the real issue is…?)
A /proc/PID/mem vulnerability
Posted Feb 6, 2012 16:01 UTC (Mon) by landley (guest, #6789) [Link]
When Linux first grew "1.2.3.x" level releases, they would stop doing them as soon as a new kernel came out, and there was a gap between the last stable and the new kernel. I asked for one more release worth of overlap, so people stuck on old kernels could see what the fixes in need of backporting were without losing some in each gap between the last dot-release in the old kernel and the new quarterly kernel release. Greg agreed and started doing that.
(Since then various people have tried to do long term support for Random Kernels Your Vendor Did Not Provide, which is utterly useless to anybody using a board support package in the embedded space, and yet they keep hoping that If We Build It, They Will Stop Using The Thing The Other Guy Already Built. But the extra overlap closing the gap for the stable releases is still a good thing anyway.)
The danger with what Linus is doing is if he DOESN'T forward that commit to the stable guys. But presumably he did that.
Rob