|
|
Subscribe / Log in / New account

Another kernel NULL pointer vulnerability

From:  Tavis Ormandy <taviso-AT-sdf.lonestar.org>
To:  full-disclosure-AT-lists.grok.org.uk, bugtraq-AT-securityfocus.com
Subject:  Linux NULL pointer dereference due to incorrect proto_ops initializations
Date:  Thu, 13 Aug 2009 20:57:53 +0200
Message-ID:  <20090813185753.GA5961@sdf.lonestar.org>
Archive‑link:  Article

Linux NULL pointer dereference due to incorrect proto_ops initializations
-------------------------------------------------------------------------

In the Linux kernel, each socket has an associated struct of operations
called proto_ops which contain pointers to functions implementing various
features, such as accept, bind, shutdown, and so on.

If an operation on a particular socket is unimplemented, they are expected
to point the associated function pointer to predefined stubs, for example if
the "accept" operation is undefined it would point to sock_no_accept(). However,
we have found that this is not always the case and some of these pointers are
left uninitialized.

This is not always a security issue, as the kernel validates the pointers at
the call site, such as this example from sock_splice_read:

static ssize_t sock_splice_read(struct file *file, loff_t *ppos,
                    struct pipe_inode_info *pipe, size_t len,
                unsigned int flags)
{
    struct socket *sock = file->private_data;

    if (unlikely(!sock->ops->splice_read))
        return -EINVAL;

    return sock->ops->splice_read(sock, ppos, pipe, len, flags);
}

But we have found an example where this is not the case; the sock_sendpage()
routine does not validate the function pointer is valid before dereferencing
it, and therefore relies on the correct initialization of the proto_ops
structure.

We have identified several examples where the initialization is incomplete:

- The SOCKOPS_WRAP macro defined in include/linux/net.h, which appears correct
  at first glance, was actually affected. This includes PF_APPLETALK, PF_IPX,
  PF_IRDA, PF_X25 and PF_AX25 families.

- Initializations were missing in other protocols, including PF_BLUETOOTH,
  PF_IUCV, PF_INET6 (with IPPROTO_SCTP), PF_PPPOX and PF_ISDN.

--------------------
Affected Software
------------------------

All Linux 2.4/2.6 versions since May 2001 are believed to be affected:

- Linux 2.4, from 2.4.4 up to and including 2.4.37.4
- Linux 2.6, from 2.6.0 up to and including 2.6.30.4

--------------------
Consequences
-----------------------

This issue is easily exploitable for local privilege escalation. In order to
exploit this, an attacker would create a mapping at address zero containing
code to be executed with privileges of the kernel, and then trigger a
vulnerable operation using a sequence like this:

/* ... */
    int fdin = mkstemp(template);
    int fdout = socket(PF_PPPOX, SOCK_DGRAM, 0);

    unlink(template);

    ftruncate(fdin, PAGE_SIZE);

    sendfile(fdout, fdin, NULL, PAGE_SIZE);
/* ... */

Please note, sendfile() is just one of many ways to cause a sendpage
operation on a socket.

Successful exploitation will lead to complete attacker control of the system.

-------------------
Mitigation
-----------------------

Recent kernels with mmap_min_addr support may prevent exploitation if
the sysctl vm.mmap_min_addr is set above zero. However, administrators
should be aware that LSM based mandatory access control systems, such
as SELinux, may alter this functionality.

It should also be noted that all kernels up to 2.6.30.2 are vulnerable to
published attacks against mmap_min_addr.

-------------------
Solution
-----------------------

Linus committed a patch correcting this issue on 13th August 2009.

http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-...

-------------------
Credit
-----------------------

This bug was discovered by Tavis Ormandy and Julien Tinnes of the Google
Security Team.


-- 
-------------------------------------
taviso@sdf.lonestar.org | finger me for my gpg key.
-------------------------------------------------------




to post comments

Another kernel NULL pointer vulnerability

Posted Aug 14, 2009 4:33 UTC (Fri) by spender (guest, #23067) [Link] (2 responses)

Exploit code has been at:
http://grsecurity.net/~spender/wunderbar_emporium.tgz

It works on any vulnerable kernel (I've tested extensively here on at least 15 VMs, x86, x64, 2.4, 2.6, with creds, without creds, 4k stacks, 8k stacks).

-Brad

Another kernel NULL pointer vulnerability

Posted Aug 15, 2009 16:30 UTC (Sat) by forcer (guest, #60276) [Link] (1 responses)

are you sure this is the right exploit? did you even look at it? this does
seems as a older pulseaudio bug, which is already patched as far as I know.

Another kernel NULL pointer vulnerability

Posted Aug 15, 2009 17:34 UTC (Sat) by spender (guest, #23067) [Link]

It's supposed to work on any kernel, so it uses every public technique to mmap at 0, despite whatever protections are in place. That's why the pulseaudio stuff is present in it.

-Brad

Another kernel NULL pointer vulnerability

Posted Aug 14, 2009 5:29 UTC (Fri) by lkundrak (subscriber, #43452) [Link] (9 responses)

Is there really anyone left who did not patch their kernels to disallow mappings at page 0? (Well I didn't check if distributors issued updates with this, but I somehow assumed...)

Another kernel NULL pointer vulnerability

Posted Aug 14, 2009 5:36 UTC (Fri) by spender (guest, #23067) [Link] (8 responses)

See my post in the other thread. There's a vulnerability in SELinux where it overrides the mmap_min_addr setting, where by default on all RHEL installs, any logged in user is able to mmap at 0, regardless of the mmap_min_addr setting. My exploit still works on the latest RHEL kernel.

-Brad

Another kernel NULL pointer vulnerability

Posted Aug 14, 2009 11:09 UTC (Fri) by jamesmrh (guest, #31622) [Link] (7 responses)

Just to clarify, the problem arises from the policy shipped in RHEL5, not in SELinux itself.

Eric Paris posted on the topic here:

http://eparis.livejournal.com/606.html

(see comments for further thoughts from Brad).

Note that the LSM and SELinux logic has been reworked upstream by Eric. The primary patch of interest is:

http://marc.info/?l=linux-security-module&m=124905958...

This will allow finer control over the ability to perform low mappings with better separation of DAC and MAC controls & will be pushed to Linus for 2.6.32.

Another kernel NULL pointer vulnerability

Posted Aug 14, 2009 17:43 UTC (Fri) by MarkWilliamson (guest, #30166) [Link] (5 responses)

> Just to clarify, the problem arises from the policy shipped in RHEL5, not
> in SELinux itself.

I had the impression from previous LWN articles that there was also a bug or, at least, an "unintended feature" in the LSM infrastructure (not specifically SELinux, then), which disabled the normal Linux checking for minimum mmap-able address when an LSM was installed.

So one *aspect* of the problem is affected by the presence of SELinux (or other LSMs), even though SELinux itself may not contain the bug. Is that correct too?

Another kernel NULL pointer vulnerability

Posted Aug 14, 2009 18:00 UTC (Fri) by spender (guest, #23067) [Link] (1 responses)

Yea, they used a bunch of weasel words like "dumb idea"/"stupid behavior" etc instead of calling it what it was: a vulnerability. I hear finally they are going to call it as such and issue a CVE (and then hopefully actually resolve the problem, which is currently unfixed). And it only took them an entire month, having my CVE request ignored, releasing two exploits, one of which works against all Red Hat/Fedora/RHEL versions since 2001, having them lie about putting in their own CVE request (they asked me to cancel my CVE request so they could put their own in) to have it pushed aside as an "errata" and then ultimately left unfixed.

-Brad

Another kernel NULL pointer vulnerability

Posted Aug 15, 2009 11:39 UTC (Sat) by trasz (guest, #45786) [Link]

In this case, it's more a design mistake in LSM - allowing a policy to _lower_ the security, i.e. to permit something that would be otherwise denied - than a specific vulnerability. Vulnerability is just an effect of this problem.

Another kernel NULL pointer vulnerability

Posted Aug 15, 2009 9:36 UTC (Sat) by jamesmrh (guest, #31622) [Link] (2 responses)

The fact that it's possible at all to have weaker security with MAC enabled is a design problem in itself. LSM/SELinux doesn't disable the check inherently, but it allows a policy writer to inadvertently do so, which is what we're addressing upstream.

The SELinux policy in RHEL5 for unconfined domains (i.e. local logged in users) has no check. Eric's changes will allow the MAC and DAC checks to be properly separated, so SELinux policy can't override DAC in this case. (See Eric's blog entry, it has a much more thorough explanation).

Another kernel NULL pointer vulnerability

Posted Aug 15, 2009 14:34 UTC (Sat) by jimmybgood (guest, #26142) [Link] (1 responses)

Yes, I read Eric's blog. He's being disingenuous by claiming that while SELinux might have allowed a local user to escalate privilege, it would have been more resistant to a network attack. That might have been true in July, but it wasn't true in early August when this exploit was reported.

Having patched my kernel to 2.6.30.4 in July, this exploit would not run, with vm reporting that the page couldn't be mapped.

The problem is that SELinux is too difficult to configure forcing even quite knowledgeable sysadmins to rely on canned distro configurations, which may or may not be suitable for their particular need. In many situations (where WINE was needed), SELinux _was_ doing the right thing.

The same can be said of the hal, console-kit and policykit consortium. I'd feel more comfortable with an X server running as root, than the new unprivileged X, with hal and friends. The only way I can configure hal is to google a magic invocation and cross my fingers. I'll bet we'll see major exploits using hal, ck and/or pk coming soon.

I'm not sure what the solution is. My work around is to avoid any security solution that I can't comfortably configure and feel that I understand fully what I'm doing. That's never been the case with SELinux. I know there's a parser that will look at the logs and give you a configuration snippet, but I don't know how it works and so I don't trust it.

Another kernel NULL pointer vulnerability

Posted Aug 15, 2009 16:15 UTC (Sat) by nix (subscriber, #2304) [Link]

Even the new unprivileged X can have HAL entirely compiled out of it :)

Another kernel NULL pointer vulnerability

Posted Aug 14, 2009 18:07 UTC (Fri) by spender (guest, #23067) [Link]

SELinux could have obeyed the mmap_min_addr restriction, and further tightened it down (as not all things with CAP_SYS_RAWIO need to mmap at 0). If SELinux was doing the right thing from the beginning, the code wouldn't need any "reworking."

-Brad


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