telnetgmike / google-security-research

Automatically exported from code.google.com/p/google-security-research
0 stars 0 forks source link

OS X IOKit kernel code execution due to integer overflow in IODataQueue::enqueue #39

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
The class IODataQueue is used in various places in the kernel. There are a 
couple of exploitable integer overflow issues in the ::enqueue method:

Boolean IODataQueue::enqueue(void * data, UInt32 dataSize)
{
  const UInt32       head      = dataQueue->head;  // volatile
  const UInt32       tail      = dataQueue->tail;
  const UInt32       entrySize = dataSize + DATA_QUEUE_ENTRY_HEADER_SIZE;  <-- (a)
  IODataQueueEntry * entry;

  if ( tail >= head )
  {
    // Is there enough room at the end for the entry?
    if ( (tail + entrySize) <= dataQueue->queueSize )                      <-- (b)
    {
      entry = (IODataQueueEntry *)((UInt8 *)dataQueue->queue + tail);

      entry->size = dataSize;
      memcpy(&entry->data, data, dataSize);                                <-- (c)

The additions at (a) and (b) should be checked for overflow. In both cases, by 
supplying a large value for dataSize an attacker can reach the memcpy call at 
(c) with a length argument which is larger than the remaining space in the 
queue buffer.

The majority of this PoC involves setting up the conditions to actually be able 
to reach a call to ::enqueue with a controlled dataSize argument, the bug 
itself it quite simple.

This PoC creates an IOHIDLibUserClient (IOHIDPointingDevice) and calls the 
create_queue externalMethod to create an IOHIDEventQueue (which inherits from 
IODataQueue.) This is the queue which will have the ::enqueue method invoked 
with the large dataSize argument.

The PoC then calls IOConnectMapMemory with a memoryType argument of 0 which 
maps an array of IOHIDElementValues into userspace:

typedef struct _IOHIDElementValue
{
  IOHIDElementCookie  cookie;
  UInt32        totalSize;
  AbsoluteTime    timestamp;
  UInt32        generation;
  UInt32        value[1];
}IOHIDElementValue;

The first dword of the mapped memory is a cookie value and the second is a size.

When the IOHIDElementPrivate::processReport method is invoked (in response to 
an HID event) if there are any listening queues then the IOHIDElementValue will 
be enqueued - and the size is in shared memory :-)

The PoC calls the startQueue selector to start the listening queue then calls 
addElementToQueue passing the cookie for the first IOHIDElementValue and the ID 
of the listening queue.

A loop then overwrites the totalSize field of the IOHIDElementValue in shared 
memory with 0xfffffffe. When the processReport method is called this will call 
IODataQueue::enqueue and overflow the calculation of entry size such that it 
will attempt to memcpy 0xfffffffe bytes. Note that the size of the queue buffer 
is also attacked controlled, and the kernel is 64-bit, so a 4gb memcpy is 
almost certainly exploitable.

Note that lldb seems to get confused by the crash - the memcpy implementation 
uses rep movsq and lldb doesn't seem to understand the 0xf3 (rep) prefix - IDA 
disassembles the function fine though. Also the symbols for memcpy and 
real_mode_bootstrap_end seem to have the same address so the lldb backtrace 
looks weird, but it is actually memcpy.

Original issue reported on code.google.com by ianb...@google.com on 26 Jun 2014 at 1:33

Attachments:

GoogleCodeExporter commented 9 years ago

Original comment by ianb...@google.com on 26 Jun 2014 at 1:35

GoogleCodeExporter commented 9 years ago

Original comment by ianb...@google.com on 26 Jun 2014 at 1:36

GoogleCodeExporter commented 9 years ago

Original comment by ianb...@google.com on 22 Aug 2014 at 9:38

GoogleCodeExporter commented 9 years ago
http://support.apple.com/kb/HT6441 (i.e. also affected iOS)
http://support.apple.com/kb/HT6443

Original comment by cev...@google.com on 23 Sep 2014 at 9:33

GoogleCodeExporter commented 9 years ago
This CVE is referenced again in: http://support.apple.com/en-us/HT204244

Original comment by ianb...@google.com on 5 Feb 2015 at 12:08