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 [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to