xorl %eax, %eax

Linux kernel ACPI Video Integer Overflows

with 10 comments

This was also reported by Michael Buesch and again, it can be triggered only by users who have write access to the equivalent procfs file. Here is the first buggy routine as seen in drivers/acpi/video.c of 2.6.30 release of the Linux kernel.

static ssize_t
acpi_video_device_write_state(struct file *file,
                              const char __user * buffer,
                              size_t count, loff_t * data)
{
        int status;
        struct seq_file *m = file->private_data;
        struct acpi_video_device *dev = m->private;
        char str[12] = { 0 };
        u32 state = 0;


        if (!dev || count + 1 > sizeof str)
                return -EINVAL;

        if (copy_from_user(str, buffer, count))
                return -EFAULT;

        str[count] = 0;
        state = simple_strtoul(str, NULL, 0);
        state &= ((1ul << 31) | (1ul << 30) | (1ul << 0));

        status = acpi_video_device_set_state(dev, state);

        if (status)
                return -EFAULT;

        return count;
}
&#91;/sourcecode&#93;

In the above code, if user requests sizeof(size_t) bytes to be copied. Meaning 'count' will be equal to that value, then during the first if condition 'count' will wrap around zero and of course, 0 is larger than sizeof(str). The following copy_from_user() will result to an attempt to copy huge amount of data to kernel space. This was fixed by changing the if statement accordingly:

&#91;sourcecode language="c"&#93;
-	if (!dev || count + 1 > sizeof str)
+	if (!dev || count >= sizeof str)
 		return -EINVAL;

And the exact same vulnerability was also fixed in acpi_video_device_write_brightness(), acpi_video_bus_write_POST() and acpi_video_bus_write_DOS().

Written by xorl

July 19, 2009 at 16:52

Posted in bugs, linux

10 Responses

Subscribe to comments with RSS.

  1. a few questions regarding exploitability
    1) with count as -1 won’t copy_from_user fail? I’m fairly sure I remember copyfromuser doing full bounds checking before starting any copying
    2) Doesn’t write do some value checking for big writes?

    #1 makes it seem unlikely the bug can even be triggered

    clueless reader

    July 19, 2009 at 19:50

  2. and #2

    clueless reader

    July 19, 2009 at 19:51

  3. Hello dear a… oh, I mean “clueless reader”. IIRC copy_from_user will initially invoke access_ok() which on x86 and x86_64 does only a check of addr + size < segment limit or something.
    So, if you pass this check which is really likely that you will, you will corrupt enough memory to at least cause an oops.

    2) I had a look at fs/read_write.c (on 2.6.18) and the VFS layer performs a access_ok() check but then there is a rw_verify_area() which among other has this code:

            if (unlikely((ssize_t) count < 0))
                   goto Einval;
    

    Thanks for the questions!

    xorl

    July 19, 2009 at 20:40

  4. did anyone trigger it?

    a....clueless reader ;)

    July 20, 2009 at 09:47

  5. i think there might be some other ways to get to that function, but i have no clue

    a....clueless reader ;)

    July 20, 2009 at 09:48

  6. xorl: come online and I’ll tell you some tales of copy_from_user ;)

    spender

    July 20, 2009 at 13:22

  7. “In the above code, if user requests sizeof(size_t) bytes to be copied.”

    I think this should be corrected to ((size_t) -1), because copying four / eight bytes won’t really do any harm. Despite the grammar fail. :p

    Keep up the good work, I’m a regular reader of your fantastic blag.

    oxff

    July 20, 2009 at 13:26

  8. “a….clueless reader ;)” Hi again, a*. I haven’t trigger it but I also haven’t spend any time on it yet.

    oxff you’re right. Thanks for this correction! :)

    spender I cannot connect to IRC now :(
    I cannot even read what you’re saying (on IRC) at the moment :p

    xorl

    July 20, 2009 at 14:40

  9. where are you guys hanging out on irc at?

    lulwut

    July 20, 2009 at 17:21

  10. lulwut I can only talk for myself and I don’t IRC that much :P
    If you want to contact me for something you can always email me :)

    xorl

    July 20, 2009 at 17:52


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