linux kernel IEEE1394(Firewire) driver integer overflow vulnerabilities
Linux kernel IEEE 1394(Firewire) driver - integer overflows
-----------------------------------------------------------
Link:
http://www.linux1394.org/index.php
Driver Description:
IEEE 1394 is a standard defining a high speed serial bus. This bus is also named
FireWire by Apple or i.Link by Sony. All these names refer to the same thing,
but the neutral term IEEE 1394 (or just 1394) is used on these web pages and in
the sources.
This driver is included in standard linux distros. It is located in
/usr/src/linux/drivers/ieee1394/.
Impact:
Local DOS, possible code execution
Vuln:
there exist multiple integer overflows in the memory allocation scheme of the
driver. in the write method of the driver a user buffer is copied into kernel
space. in this buffer is a request structure that contains an unsigned length
field. this field is used to allocate memory, after it is added to another
number. there are no checks to see if this overflows during integer addition.
this problem occurs in the alloc_hpsb_packet function.
the problem exists in both the 2.4 and 2.6 version of driver, 2.2 was not
checked. the functions leading up to this are spread out through a couple
files:
2.4:
-> raw1394_write() -- raw1394.c:852
-> state_connected() -- raw1394.c:806
-> handle_remote_request() -- raw1394.c:658
-> hpsb_make_writebpacket() -- ieee1394_transactions.c:357
-> alloc_hpsb_packet() -- ieee1394_core.c:114
2.6:
-> raw1394_write() -- raw1394.c:2149
-> state_connected() -- raw1394.c:2061
-> handle_async_request() -- raw1394.c:620
-> hpsb_make_writepacket() -- ieee1394_transactions.c:291
-> alloc_hpsb_packet() -- ieee1394_core.c:123
Detail:
Starting from the write() method of the driver, a user structure is copied
into kernel buffer. Depending on the state of the connection, and type of
request, eventually we get to the offending code, in 2.4 from
alloc_hpsb_packet():
+variable data_size is a size_t passed from user supplied structure+
data = kmalloc(data_size + 8, kmflags);
if (data == NULL) {
kmem_cache_free(hpsb_packet_cache, packet);
return NULL;
}
packet->data = data;
packet->data_size = data_size;
and then back in handle_remote_request():
+req->req.length was the same value used above to size the buffer
if (copy_from_user(packet->data, int2ptr(req->req.sendb), req->req.length))
{
req->req.error = RAW1394_ERROR_MEMFAULT;
}
this results in possibly gigabytes of memory being copied into a small
buffer, which will crash system. depending on the layout of the slab this
buffer lives on, some sort of exploitation may be possible. if u look around
you'll find similar issues with the read() request as well, involving packets
being allocated with incorrect lengths. the contact on sourceforge was emailed
last week and given until monday to reply. i never heard back from them, so im
submitting this here.
-- --
-sean