From: Dawson Engler <engler@csl.Stanford.EDU> To: linux-kernel@vger.kernel.org Subject: [CHECKER] 2.4.5-ac4 security holes Date: Thu, 31 May 2001 21:49:14 -0700 (PDT) Cc: mc@cs.Stanford.EDU 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/