[CHECKER] 4 security holes in 2.4.4-ac8

Dawson Engler (engler@csl.Stanford.EDU)
Tue, 29 May 2001 15:00:56 -0700 (PDT)


Hi All,

Enclosed are four bugs where 2.4.4-ac8 kernel code appears to directly
read/write user space pointers. The latter three were found after
forming equivalence classes by:
(1) recording all routines assigned to the same function pointer
field in a structure
(2) if any member of the equiv class treated a parameter as a
user-space pointer, checking that they all do.

Let me know if any of these are wrong. The first one seems pretty bad.

Dawson
-------------------------------------------------------------------------------
[BUG] raddr seems to be a user pointer, but is written at the end of
the system call.

ipc/shm.c: ERROR: system call 'sys_shmat' derefs non-tainted param= 3

asmlinkage long sys_shmat (int shmid, char *shmaddr, int shmflg, ulong *raddr)
{
struct shmid_kernel *shp;

...
*raddr = (unsigned long) user_addr;
err = 0;
if (IS_ERR(user_addr))
err = PTR_ERR(user_addr);
return err;

-----------------------------------------------------------------------------
[BUG] ./drivers/usb/bluetooth.c: dereference of 'buf' at the beginning of
the switch, and then does a copyin.

ERROR: equivalence class <struct tty_driver:write> contains
2 functions that taint parameter <2>, and 1
functions that dereference it raw.

Tainting functions
[ acm_tty_write:acm.c ]
[ serial_write:usbserial.c ]
Dereferencing functions
[ bluetooth_write:bluetooth.c ]

switch (*buf) {
/* First byte indicates the type of packet */
case CMD_PKT:
/* dbg(__FUNCTION__ "- Send cmd_pkt len:%d", count);*/

if (in_interrupt()){
printk("cmd_pkt from interrupt!\n");
return count;
}

new_buffer = kmalloc (count-1, GFP_KERNEL);

if (!new_buffer) {
err (__FUNCTION__ "- out of memory.");
return -ENOMEM;
}

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

-------------------------------------------------------
In the equivalence class for file_operations:write: 55 functions treat
their second parameter as tainted, but two functions use it raw.

[BUG]
/* drivers/char/sbc60xxwdt.c: buf is tainted */
static ssize_t fop_write(struct file * file, const char * buf, size_t count, loff_t * ppos)
{
/* We can't seek */
if(ppos != &file->f_pos)
return -ESPIPE;

/* See if we got the magic character */
if(count)
{
size_t ofs;

/* note: just in case someone wrote the magic character
* five months ago... */
wdt_expect_close = 0;

/* now scan */
for(ofs = 0; ofs != count; ofs++)
if(buf[ofs] == 'V')
wdt_expect_close = 1;

/* Well, anyhow someone wrote to us, we should return that favour */
next_heartbeat = jiffies + WDT_HEARTBEAT;
}
return 0;
}

[BUG]
/* drivers/usb/mdc800.c: buf is tainted */
static ssize_t mdc800_device_write (struct file *file, const char *buf, size_t len, loff_t *pos)
{
int i=0;

spin_lock (&mdc800->io_lock);
if (mdc800->state != READY)
{
spin_unlock (&mdc800->io_lock);
return -EBUSY;
}
if (!mdc800->open )
{
spin_unlock (&mdc800->io_lock);
return -EBUSY;
}

while (i<len)
{
if (signal_pending (current))
{
spin_unlock (&mdc800->io_lock);
return -EINTR;
}

/* check for command start */
if (buf [i] == (char) 0x55)
{
mdc800->in_count=0;

Here's the equiv classes:

Tainting functions
[ ac_write:applicom.c ]
[ affs_file_write:file.c ]
[ block_write:ksyms.c ]
[ camera_write:dc2xx.c ]
[ cap_info_write:file_cap.c ]
[ capi_write:capi.c ]
[ capinc_raw_write:capi.c ]
[ coda_file_write:file.c ]
[ coda_psdev_write:psdev.c ]
[ cs4281_midi_write:cs4281m.c ]
[ cs4281_write:cs4281m.c ]
[ dev_irnet_write:irnet_ppp.h ]
[ dev_write:raw1394.c ]
[ ds_write:ds.c ]
[ dtlk_write:dtlk.c ]
[ emu10k1_audio_write:audio.c ]
[ emu10k1_midi_write:midi.c ]
[ generic_file_write:ksyms.c ]
[ hdr_write:file_hdr.c ]
[ hfs_file_write:file.c ]
[ hpfs_file_write:inode.c ]
[ i2cdev_write:i2c-dev.c ]
[ idetape_chrdev_write:ide-tape.c ]
[ isapnp_info_entry_write:isapnp_proc.c ]
[ isdn_write:isdn_common.c ]
[ ixj_enhanced_write:ixj.c ]
[ lp_write:lp.c ]
[ mem_write:pcilynx.c ]
[ microcode_write:microcode.c ]
[ mtd_write:mtdchar.c ]
[ mtrr_write:mtrr.c ]
[ ncp_file_write:file.c ]
[ nfs_file_write:file.c ]
[ nvram_write:nvram.c ]
[ osst_write:osst.c ]
[ pg_write:pg.c ]
[ pipe_write:pipe.c ]
[ ppp_write:ppp_generic.c ]
[ proc_bus_pci_write:proc.c ]
[ proc_mpc_write:mpoa_proc.c ]
[ qic02_tape_write:tpqic02.c ]
[ sg_write:sg.c ]
[ shmem_file_write:shmem.c ]
[ smb_file_write:file.c ]
[ st_write:st.c ]
[ tun_chr_write:tun.c ]
[ usb_audio_write:audio.c ]
[ vcs_write:vc_screen.c ]
[ write_kmem:mem.c ]
[ write_mem:mem.c ]
[ write_port:mem.c ]
[ write_profile:proc_misc.c ]
[ write_rio:rio500.c ]
[ write_scanner:scanner.c ]
[ zft_write:zftape-init.c ]
Dereferencing functions
[ fop_write:sbc60xxwdt.c ]
[ mdc800_device_write:mdc800.c ]
-
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/