xorl %eax, %eax

Linux kernel /dev/net/tun NULL Pointer Dereference

with 6 comments

This is a really cool vulnerability which was reported with a trigger code from Eugene Kapun. It affects Linux kernel 2.6.30 and it can be found in drivers/net/tun.c like that.

/* Poll */
static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
{
        struct tun_file *tfile = file->private_data;
        struct tun_struct *tun = __tun_get(tfile);
        struct sock *sk = tun->sk;
        unsigned int mask = 0;

        if (!tun)
                return POLLERR;

        DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name);

        poll_wait(file, &tun->socket.wait, wait);

        if (!skb_queue_empty(&tun->readq))
                mask |= POLLIN | POLLRDNORM;

        if (sock_writeable(sk) ||
            (!test_and_set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags) &&
             sock_writeable(sk)))
                mask |= POLLOUT | POLLWRNORM;

        if (tun->dev->reg_state != NETREG_REGISTERED)
                mask = POLLERR;

        tun_put(tun);
        return mask;
}

The bug is quite obvious. It initializes sk to tun->sk and THEN it checks if tun is NULL :P Of course, this should be done first since the compiler will optimize it and completely remove the if(!tun) check since it is performed after the assignment. Because of this, the above vulnerability can result in a nice exploitable NULL pointer dereference. This was fixed by updating the code like that:

-	struct sock *sk = tun->sk;
+	struct sock *sk;
 	unsigned int mask = 0;
 
 	if (!tun)
 		return POLLERR;
 
+	sk = tun->sk;
+
 	DBG(KERN_INFO "%s: tun_chr_poll\n", tun->dev->name);

P.S.: spender, ok… I will post similar bugs in the future :P

About these ads

Written by xorl

July 17, 2009 at 01:25

Posted in bugs, linux

6 Responses

Subscribe to comments with RSS.

  1. xorl,

    Where is your original post on this “silent fix” that spender refers to in his comments? I couldn’t find it here on the blog, though honestly I’m not quite sure what I’m looking for.

    Thanks,

    –Mish

    Mish

    July 17, 2009 at 14:19

  2. Mish, I haven’t posted anything before for that particular bug. I believe spender was referring in general to the silently fixed vulnerabilities in the Linux kernel.

    xorl

    July 17, 2009 at 15:40

  3. Mish: xorl is right, I just was asking him in my exploit to report more on silently fixed vulnerabilities in the Linux kernel in general :)

    Bradley Spengler

    July 18, 2009 at 00:10

  4. /dev/net/tun is rw only for root in most distributions. I’m missing something here.

    Alfred

    July 22, 2009 at 15:29

  5. @Alfred: This question has already been answered by spender (the author of the Cheddar Bay exploit) and you can read it here:
    http://xorl.wordpress.com/2009/07/18/linux-kernel-nvram-integer-overflow/#comment-300
    Hope this helps. :)

    xorl

    July 22, 2009 at 15:36

  6. Ahh I knew it!! :)

    Thanks Xorl

    Alfred

    July 22, 2009 at 15:48


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 60 other followers