Bug 2966

Summary: possible buffer overflow in DVD handling
Product: Drivers Reporter: Marcus Meissner (meissner)
Component: OtherAssignee: drivers_other
Severity: normal CC: bunk, greg
Priority: P2    
Hardware: i386   
OS: Linux   
Kernel Version: 2.6.5 Tree: Mainline
Regression: No
Attachments: Fix typo

Description Marcus Meissner 2004-06-27 12:25:07 UTC
Distribution: none 
Hardware Environment: none 
Software Environment: none 
Problem Description: 
reading through drivers/cdrom/cdrom.c:dvd_read_bca() shows a potential 
buf[4+188] is allocated on the stack, however cgc.cmd[9] and cgc.buflen are 
set to 255. 
This can be exploited by a custom made USB Storage device and used 
for local privilege escalation. (aka plug-in this usb device to get root). 
Steps to reproduce: 
review the function for buffer overflow again.
Comment 1 Marcus Meissner 2004-06-27 12:29:04 UTC
same goes for cdrom_mrw_set_lba_space(). 
it senses information and uses a 16bit value for a new buffer length,  
using a 16 BYTE buffer on the stack. 
Could also be exploited by custom made USB device. 
(For both the user needs read access to the CDROM device, this is usually 
the case for most distributions.) 
Comment 2 Matthew Dharm 2004-07-10 23:40:44 UTC
USB really has nothing to do with this bug.  It could also be reproduced with 
a custom ATAPI device, but that's just a little less likely.

This needs to be handled by the CDROM driver folks.
Comment 3 Adrian Bunk 2006-07-04 14:51:47 UTC
I checked both 2.6.5 and the current tree, and both contain:

static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s)
        int ret;
        u_char buf[4 + 188];
        if (s->bca.len < 12 || s->bca.len > 188) {
                cdinfo(CD_WARNING, "Received invalid BCA length (%d)\n",
                return -EIO;
        memcpy(s->bca.value, &buf[4], s->bca.len);

I don't see the problem you are referring to - the check is there.

Comment 4 Marcus Meissner 2006-07-04 22:07:50 UTC
Actually I wondered about this line: 
        cgc.cmd[9] = cgc.buflen = 0xff; 
You overwrite the just set buflen in the cgc of 192 by 255 
and this could overwrite buf by cdo->generic_packet(). 
In case the device returns between 193 and 255 bytes 
it will be able to overwrite the buf[188 +4]. 
Comment 5 Marcus Meissner 2006-07-04 22:16:27 UTC
note that the buffer is filled by the remote procedure even before this bca.len 
I think you just need to add  
if (cgc->data_direction == CGC_DATA_READ) 
memset(cgc.buf, 0x42, cgc.buflen); 
to ide/ide-cd.c::ide_cdrom_packet() and see it crash and burn in this call. 
cgc.buflen should not be overwritten here. 
Comment 6 Jens Axboe 2006-07-05 03:11:10 UTC
It's a typo, it should read:

cgc.cmd[9] = cgc.buflen & 0xff;

to mask high bits of the length. It doesn't use the high 8 bits for transfer
length, since we are always < 256 for this case.
Comment 7 Jens Axboe 2006-07-05 03:12:48 UTC
Created attachment 8489 [details]
Fix typo
Comment 8 Marcus Meissner 2006-07-06 03:43:22 UTC
Comment 9 Adrian Bunk 2006-07-08 12:08:41 UTC
Marcus, please accept my apology for misunderstanding your bug report.
Comment 10 Diego Calleja 2006-08-04 05:05:06 UTC
This bug should have been closed long time ago, the fix is already merged in the
main tree