xorl %eax, %eax

Linux kernel Freescale MPC52xx PSC Off-by-One Read

leave a comment »

I was reading 2.6.30’s ChangeLog and I came across that one. This was reported by Roel Kluin, the bug is located at drivers/serial/mpc52xx_uart.c and the vulnerable function is this:

static int __init
mpc52xx_console_setup(struct console *co, char *options)
{
        struct uart_port *port = &mpc52xx_uart_ports[co->index];
        struct device_node *np = mpc52xx_uart_nodes[co->index];
        unsigned int uartclk;
        struct resource res;
        int ret;

        int baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
        int bits = 8;
        int parity = 'n';
        int flow = 'n';

        pr_debug("mpc52xx_console_setup co=%p, co->index=%i, options=%s\n",
                 co, co->index, options);

        if ((co->index < 0) || (co->index > MPC52xx_PSC_MAXNUM)) {
                pr_debug("PSC%x out of range\n", co->index);
                return -EINVAL;
        }
             ...
        pr_debug("Console on ttyPSC%x is %s\n",
                 co->index, mpc52xx_uart_nodes[co->index]->full_name);
         ...
        return uart_set_options(port, co, baud, parity, bits, flow);
}

This function is used for setting up the console. Its first argument, which is a pointer to a console structure that is defined in include/linux/console.h, contains information about the console such as console name, various callback functions for read, write, setup etc. It also contains a short signed integer that is used as an index. The above snippet includes a range check for that index being negative as well as for index values larger than MPC52xx_PSC_MAXNUM. However, if PSC is not greater than MPC52xx_PSC_MAXNUM but it is equal to that value, pr_debug() will attempt to read: mpc52xx_uart_nodes[MPC52xx_PSC_MAXNUM]->full_name which will result in an off-by-one read operation. The patch to this bug was:


-    if ((co->index < 0) || (co->index > MPC52xx_PSC_MAXNUM)) {
+    if ((co->index < 0) || (co->index >= MPC52xx_PSC_MAXNUM)) {
         pr_debug("PSC%x out of range\n", co->index);

Written by xorl

June 10, 2009 at 16:39

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