New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 5 users
Status: Fixed
Owner:
Email to this user bounced
Closed: Sep 2014



Sign in to add a comment
OS X IOKit kernel code execution due to integer overflow in IODataQueue::enqueue
Project Member Reported by ianbeer@google.com, Jun 26 2014 Back to list
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.
 
hidlib_enqueue_overflow.c
6.7 KB Download
Project Member Comment 1 by ianbeer@google.com, Jun 26 2014
Labels: Reported-2014-June-26
Project Member Comment 2 by ianbeer@google.com, Jun 26 2014
Labels: Id-607452866
Project Member Comment 3 by ianbeer@google.com, Aug 22 2014
Labels: Deadline-90
Comment 4 by cevans@google.com, Sep 23 2014
Labels: -Restrict-View-Commit -Reported-2014-June-26 Reported-2014-Jun-26 CVE-2014-4389 Fixed-2014-Sep-17 Product-iOS-Kernel
Status: Fixed
http://support.apple.com/kb/HT6441 (i.e. also affected iOS)
http://support.apple.com/kb/HT6443
Project Member Comment 5 by ianbeer@google.com, Feb 5 2015
This CVE is referenced again in: http://support.apple.com/en-us/HT204244
Sign in to add a comment