xorl %eax, %eax

CVE-2011-1495: Linux kernel /dev/mpt2ctl Arbitary Kernel Memory Read

leave a comment »

Continuing from the previous CVE-2011-1494 vulnerability, this one also resides in the _ctl_diag_read_buffer() function. More specifically, here is the code.

/**
 * _ctl_diag_read_buffer - request for copy of the diag buffer
 * @arg - user space buffer containing ioctl content
 * @state - NON_BLOCKING or BLOCKING
 */
static long
_ctl_diag_read_buffer(void __user *arg, enum block_state state)
{
        struct mpt2_diag_read_buffer karg;
        struct mpt2_diag_read_buffer __user *uarg = arg;
    ...
        if (copy_to_user((void __user *)uarg->diagnostic_data,
            diag_data, karg.bytes_to_read)) {
                printk(MPT2SAS_ERR_FMT "%s: Unable to write "
                    "mpt_diag_read_buffer_t data @ %p\n", ioc->name,
                    __func__, diag_data);
                return -EFAULT;
        }
    ...
 out:

        ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
        mutex_unlock(&ioc->ctl_cmds.mutex);
        return rc;
}

As you can see it uses the user derived ‘karg.bytes_to_read’ in order to determine the number of Bytes to copy back to the user-space. By doing this a user could read arbitrary kernel memory. The fix to this bug was to add some bound checks that will truncate the request if it is too large.


+	/* Truncate data on requests that are too large */
+	if ((diag_data + karg.bytes_to_read < diag_data) ||
+	    (diag_data + karg.bytes_to_read > request_data + request_size))
+		copy_size = request_size - karg.starting_offset;
+	else
+		copy_size = karg.bytes_to_read;
+
 	if (copy_to_user((void __user *)uarg->diagnostic_data,
-	    diag_data, karg.bytes_to_read)) {
+	    diag_data, copy_size)) {
 		printk(MPT2SAS_ERR_FMT "%s: Unable to write "
 		    "mpt_diag_read_buffer_t data @ %p\n", ioc->name,
 		    __func__, diag_data);

Written by xorl

April 29, 2011 at 20:05

Posted in bugs, linux

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