Skip to content

Commit

Permalink
xnu-2422.115.4
Browse files Browse the repository at this point in the history
  • Loading branch information
Darwin authored and das committed Jun 4, 2017
1 parent 2a67609 commit bf0ce81
Show file tree
Hide file tree
Showing 13 changed files with 317 additions and 41 deletions.
3 changes: 3 additions & 0 deletions config/IOKit.x86_64.exports
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ __ZN17IOPolledInterface28_RESERVEDIOPolledInterface13Ev
__ZN17IOPolledInterface28_RESERVEDIOPolledInterface14Ev
__ZN17IOPolledInterface28_RESERVEDIOPolledInterface15Ev
__ZN17IOSharedDataQueue11withEntriesEjj
__ZN17IOSharedDataQueue12getQueueSizeEv
__ZN17IOSharedDataQueue12setQueueSizeEj
__ZN17IOSharedDataQueue12withCapacityEj
__ZN17IOSharedDataQueue16initWithCapacityEj
__ZN17IOSharedDataQueue27_RESERVEDIOSharedDataQueue0Ev
Expand All @@ -216,6 +218,7 @@ __ZN17IOSharedDataQueue27_RESERVEDIOSharedDataQueue5Ev
__ZN17IOSharedDataQueue27_RESERVEDIOSharedDataQueue6Ev
__ZN17IOSharedDataQueue27_RESERVEDIOSharedDataQueue7Ev
__ZN17IOSharedDataQueue7dequeueEPvPj
__ZN17IOSharedDataQueue7enqueueEPvj
__ZN18IOMemoryDescriptor10setMappingEP4taskyj
__ZN18IOMemoryDescriptor10writeBytesEyPKvy
__ZN18IOMemoryDescriptor11makeMappingEPS_P4taskyjyy
Expand Down
2 changes: 1 addition & 1 deletion config/MasterVersion
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
13.3.0
13.4.0

# The first line of this file contains the master version number for the kernel.
# All other instances of the kernel version in xnu are derived from this file.
Expand Down
14 changes: 14 additions & 0 deletions iokit/IOKit/IOSharedDataQueue.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class IOSharedDataQueue : public IODataQueue
OSDeclareDefaultStructors(IOSharedDataQueue)

struct ExpansionData {
UInt32 queueSize;
};
/*! @var reserved
Reserved for future use. (Internal use only) */
Expand All @@ -61,6 +62,9 @@ class IOSharedDataQueue : public IODataQueue
protected:
virtual void free();

UInt32 getQueueSize();
Boolean setQueueSize(UInt32 size);

public:
/*!
* @function withCapacity
Expand Down Expand Up @@ -116,6 +120,16 @@ class IOSharedDataQueue : public IODataQueue
*/
virtual Boolean dequeue(void *data, UInt32 *dataSize);

/*!
* @function enqueue
* @abstract Enqueues a new entry on the queue.
* @discussion This method adds a new data entry of dataSize to the queue. It sets the size parameter of the entry pointed to by the tail value and copies the memory pointed to by the data parameter in place in the queue. Once that is done, it moves the tail to the next available location. When attempting to add a new entry towards the end of the queue and there isn't enough space at the end, it wraps back to the beginning.<br> If the queue is empty when a new entry is added, sendDataAvailableNotification() is called to send a message to the user process that data is now available.
* @param data Pointer to the data to be added to the queue.
* @param dataSize Size of the data pointed to by data.
* @result Returns true on success and false on failure. Typically failure means that the queue is full.
*/
virtual Boolean enqueue(void *data, UInt32 dataSize);

OSMetaClassDeclareReservedUnused(IOSharedDataQueue, 0);
OSMetaClassDeclareReservedUnused(IOSharedDataQueue, 1);
OSMetaClassDeclareReservedUnused(IOSharedDataQueue, 2);
Expand Down
35 changes: 30 additions & 5 deletions iokit/Kernel/IODataQueue.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <IOKit/IODataQueueShared.h>
#include <IOKit/IOLib.h>
#include <IOKit/IOMemoryDescriptor.h>
#include <libkern/OSAtomic.h>

#ifdef enqueue
#undef enqueue
Expand Down Expand Up @@ -79,6 +80,10 @@ Boolean IODataQueue::initWithCapacity(UInt32 size)
return false;
}

if (size > UINT32_MAX - DATA_QUEUE_MEMORY_HEADER_SIZE) {
return false;
}

allocSize = round_page(size + DATA_QUEUE_MEMORY_HEADER_SIZE);

if (allocSize < size) {
Expand All @@ -99,6 +104,16 @@ Boolean IODataQueue::initWithCapacity(UInt32 size)

Boolean IODataQueue::initWithEntries(UInt32 numEntries, UInt32 entrySize)
{
// Checking overflow for (numEntries + 1)*(entrySize + DATA_QUEUE_ENTRY_HEADER_SIZE):
// check (entrySize + DATA_QUEUE_ENTRY_HEADER_SIZE)
if ((entrySize > UINT32_MAX - DATA_QUEUE_ENTRY_HEADER_SIZE) ||
// check (numEntries + 1)
(numEntries > UINT32_MAX-1) ||
// check (numEntries + 1)*(entrySize + DATA_QUEUE_ENTRY_HEADER_SIZE)
(entrySize + DATA_QUEUE_ENTRY_HEADER_SIZE > UINT32_MAX/(numEntries+1))) {
return false;
}

return (initWithCapacity((numEntries + 1) * (DATA_QUEUE_ENTRY_HEADER_SIZE + entrySize)));
}

Expand All @@ -120,10 +135,20 @@ Boolean IODataQueue::enqueue(void * data, UInt32 dataSize)
const UInt32 entrySize = dataSize + DATA_QUEUE_ENTRY_HEADER_SIZE;
IODataQueueEntry * entry;

// Check for overflow of entrySize
if (dataSize > UINT32_MAX - DATA_QUEUE_ENTRY_HEADER_SIZE) {
return false;
}
// Check for underflow of (dataQueue->queueSize - tail)
if (dataQueue->queueSize < tail) {
return false;
}

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

Expand All @@ -133,8 +158,8 @@ Boolean IODataQueue::enqueue(void * data, UInt32 dataSize)
// The tail can be out of bound when the size of the new entry
// exactly matches the available space at the end of the queue.
// The tail can range from 0 to dataQueue->queueSize inclusive.

dataQueue->tail += entrySize;
OSAddAtomic(entrySize, (SInt32 *)&dataQueue->tail);
}
else if ( head > entrySize ) // Is there enough room at the beginning?
{
Expand All @@ -153,7 +178,7 @@ Boolean IODataQueue::enqueue(void * data, UInt32 dataSize)
}

memcpy(&dataQueue->queue->data, data, dataSize);
dataQueue->tail = entrySize;
OSCompareAndSwap(dataQueue->tail, entrySize, &dataQueue->tail);
}
else
{
Expand All @@ -171,7 +196,7 @@ Boolean IODataQueue::enqueue(void * data, UInt32 dataSize)

entry->size = dataSize;
memcpy(&entry->data, data, dataSize);
dataQueue->tail += entrySize;
OSAddAtomic(entrySize, (SInt32 *)&dataQueue->tail);
}
else
{
Expand Down
Loading

0 comments on commit bf0ce81

Please sign in to comment.