[CHECKER] 2.4.5-ac4 security holes

From: Dawson Engler (engler@csl.Stanford.EDU)
Date: Fri Jun 01 2001 - 00:49:14 EDT

  • Next message: Dawson Engler: "[CHECKER] 2.4.5-ac4 use of freed pointers"

    Hi All,

    Here's a few apparent security holes in 2.4.5-ac4. The biggest is in
    fs/ioctl.c where it looks like a new option was added that seems to
    write directly to the user pointer, essentially giving anyone complete
    control over the machine.

    4 | drivers/net/wan/cosa.c
    2 | drivers/usb/bluetooth.c
    1 | drivers/isdn/eicon/linchr.c
    1 | drivers/sound/wavfront.c
    1 | fs/ioctl.c

    ---------------------------------------------------------
    [BUG] looks really broken.
    /u2/engler/mc/oses/linux/2.4.5-ac4/fs/ioctl.c:108:sys_ioctl: ERROR:PARAM:70:108: Deref tainted var 'arg' (tainted from line 70)
                    case FIONCLEX:
                            set_close_on_exec(fd, 0);
                            break;

                    case FIONBIO:
    Start --->
                            if ((error = get_user(on, (int *)arg)) != 0)

            ... DELETED 32 lines ...

                    case FIOQSIZE:
                            if (S_ISDIR(filp->f_dentry->d_inode->i_mode) ||
                                S_ISREG(filp->f_dentry->d_inode->i_mode) ||
                                S_ISLNK(filp->f_dentry->d_inode->i_mode))
    Error --->
                                    *(loff_t *)arg = inode_get_bytes(filp->f_dentry->d_inode);
                            else
                                    error = -ENOTTY;
                            break;

    ---------------------------------------------------------
    [BUG] sure seems like it. In general, all 4 dereferences seem pretty bad.
    /u2/engler/mc/oses/linux/2.4.5-ac4/drivers/net/wan/cosa.c:1049:cosa_download: ERROR:PARAM:1046:1049: Deref tainted var 'd' (tainted from line 1046)
                    return -EPERM;
            }

            if (get_user(addr, &(d->addr)) ||
                __get_user(len, &(d->len)) ||
    Start --->
                __get_user(code, &(d->code)))
                    return -EFAULT;

    Error --->
            if (d->addr < 0 || d->addr > COSA_MAX_FIRMWARE_SIZE)
                    return -EINVAL;
            if (d->len < 0 || d->len > COSA_MAX_FIRMWARE_SIZE)
                    return -EINVAL;
    ---------------------------------------------------------
    [BUG] why copy it in then use the inital thing?
    /u2/engler/mc/oses/linux/2.4.5-ac4/drivers/net/wan/cosa.c:1057:cosa_download: ERROR:PARAM:1046:1057: Deref tainted var 'd' (tainted from line 1046)
                    return -EPERM;
            }

            if (get_user(addr, &(d->addr)) ||
                __get_user(len, &(d->len)) ||
    Start --->
                __get_user(code, &(d->code)))
                    return -EFAULT;

            if (d->addr < 0 || d->addr > COSA_MAX_FIRMWARE_SIZE)
                    return -EINVAL;
            if (d->len < 0 || d->len > COSA_MAX_FIRMWARE_SIZE)
                    return -EINVAL;

            /* If something fails, force the user to reset the card */
            cosa->firmware_status &= ~(COSA_FW_RESET|COSA_FW_DOWNLOAD);

    Error --->
            if ((i=download(cosa, d->code, len, addr)) < 0) {
                    printk(KERN_NOTICE "cosa%d: microcode download failed: %d\n",
                            cosa->num, i);
                    return -EIO;
    ---------------------------------------------------------
    [BUG] seems retty clear
    /u2/engler/mc/oses/linux/2.4.5-ac4/drivers/sound/wavfront.c:2049:wavefront_oss_ioctl: ERROR:PARAM:2072:2049: tainted var 'arg' (from line 2072) used as arg 0 to 'memcpy'
            int err;

            switch (cmd) {
            case SNDCTL_SYNTH_INFO:
                    memcpy (&((char *) arg)[0], &wavefront_info,
    Error --->
                            sizeof (wavefront_info));

            ... DELETED 17 lines ...

                            return dev.freemem;
                    }
                    break;

            case SNDCTL_SYNTH_CONTROL:
    Start --->
                    copy_from_user (&wc, arg, sizeof (wc));

                    if ((err = wavefront_synth_control (cmd, &wc)) == 0) {
                            copy_to_user (arg, &wc, sizeof (wc));
    ---------------------------------------------------------
    [BUG] fixed in ac5, I believe.
    /u2/engler/mc/oses/linux/2.4.5-ac4/drivers/usb/bluetooth.c:438:bluetooth_write: ERROR:PARAM:461:438: Deref tainted var 'buf' (tainted from line 461)
            }

    #ifdef DEBUG
            printk (KERN_DEBUG __FILE__ ": " __FUNCTION__ " - length = %d, data = ", count);
            for (i = 0; i < count; ++i) {
    Error --->
                    printk ("%.2x ", buf[i]);

            ... DELETED 17 lines ...

                                    err (__FUNCTION__ "- out of memory.");
                                    return -ENOMEM;
                            }

                            if (from_user)
    Start --->
                                    copy_from_user (new_buffer, buf+1, count-1);
                            else
                                    memcpy (new_buffer, buf+1, count-1);

    ---------------------------------------------------------
    [BUG]
    /u2/engler/mc/oses/linux/2.4.5-ac4/drivers/usb/bluetooth.c:431:bluetooth_write: ERROR:PARAM:461:431: Deref tainted var 'buf' (tainted from line 461)
            if (count == 0) {
                    dbg(__FUNCTION__ " - write request of 0 bytes");
                    return 0;
            }
            if (count == 1) {
    Error --->
                    dbg(__FUNCTION__ " - write request only included type %d", buf[0]);

            ... DELETED 24 lines ...

                                    err (__FUNCTION__ "- out of memory.");
                                    return -ENOMEM;
                            }

                            if (from_user)
    Start --->
                                    copy_from_user (new_buffer, buf+1, count-1);
                            else
                                    memcpy (new_buffer, buf+1, count-1);

    ---------------------------------------------------------
    [BUG] [RESURRECTED] Should be fixed in ac5, though.
    /u2/engler/mc/oses/linux/2.4.5-ac4/drivers/isdn/eicon/linchr.c:128:do_ioctl: ERROR:PARAM:60:128: tainted var 'arg' (from line 60) used as arg 0 to 'DivasGetList'
            mem_block_t mem_block;

            switch (command)
            {
                    case DIA_IOCTL_CONFIG:
    Start --->
                            if (copy_from_user(&DivaConfig, (void *)arg, sizeof(dia_config_t)))

            ... DELETED 62 lines ...

                    case DIA_IOCTL_GET_LIST:
                            DPRINTF(("divas: DIA_IOCTL_GET_LIST"));
                            
                            if (!verify_area(VERIFY_WRITE, (void *)arg, sizeof(dia_card_list_t)))
                            {
    Error --->
                                    DivasGetList((dia_card_list_t *)arg);
                            }
                            else
                            {

    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/



    This archive was generated by hypermail 2b29 : Fri Jun 01 2001 - 00:52:57 EDT