X-Git-Url: https://git.saurik.com/apple/securityd.git/blobdiff_plain/f7aa9f666a1c7ab343b4ce8f1677ea253c4e126e..4cd1cad0dea00daa03e1b54fdf2797a02373ad5b:/src/SharedMemoryServer.cpp diff --git a/src/SharedMemoryServer.cpp b/src/SharedMemoryServer.cpp index 46bc1dc..699542c 100644 --- a/src/SharedMemoryServer.cpp +++ b/src/SharedMemoryServer.cpp @@ -3,13 +3,29 @@ #include #include #include +#include +#include +#include +#include +static const char* kPrefix = "/private/var/db/mds/messages/se_"; SharedMemoryServer::SharedMemoryServer (const char* segmentName, SegmentOffsetType segmentSize) : mSegmentName (segmentName), mSegmentSize (segmentSize) { + mFileName = kPrefix; + mFileName += segmentName; + + // make the mds directory, just in case it doesn't exist + mkdir("/var/db/mds", 1777); + mkdir("/var/db/mds/messages", 0755); + + // make the file name + // clean any old file away + unlink (mFileName.c_str ()); + // open the file - int segmentDescriptor = shm_open (segmentName, O_RDWR | O_CREAT, S_IRWXU | S_IRGRP | S_IROTH); + int segmentDescriptor = open (mFileName.c_str (), O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (segmentDescriptor < 0) { return; @@ -25,10 +41,13 @@ SharedMemoryServer::SharedMemoryServer (const char* segmentName, SegmentOffsetTy if (mSegment == (u_int8_t*) -1) // can't map the memory? { mSegment = NULL; - shm_unlink (segmentName); + unlink (mFileName.c_str()); } - SetProducerCount (0); + mDataPtr = mDataArea = mSegment + sizeof(SegmentOffsetType); + mDataMax = mSegment + segmentSize;; + + SetProducerOffset (0); } @@ -45,42 +64,41 @@ SharedMemoryServer::~SharedMemoryServer () munmap (mSegment, mSegmentSize); // mark the segment for deletion - shm_unlink (mSegmentName.c_str ()); + unlink (mFileName.c_str ()); } const SegmentOffsetType kSegmentLength = 0, - kDomainOffset = kSegmentLength + sizeof (SegmentOffsetType), - kEventTypeOffset = kDomainOffset + sizeof (SegmentOffsetType), - kHeaderLength = kEventTypeOffset + sizeof (SegmentOffsetType); + kCRCOffset = kSegmentLength + sizeof(SegmentOffsetType), + kDomainOffset = kCRCOffset + sizeof(SegmentOffsetType), + kEventTypeOffset = kDomainOffset + sizeof(SegmentOffsetType), + kHeaderLength = kEventTypeOffset + sizeof(SegmentOffsetType) - kCRCOffset; void SharedMemoryServer::WriteMessage (SegmentOffsetType domain, SegmentOffsetType event, const void *message, SegmentOffsetType messageLength) { - // get the current producer count - SegmentOffsetType pCount = GetProducerCount (); + // assemble the final message + ssize_t messageSize = kHeaderLength + messageLength; + u_int8_t finalMessage[messageSize]; + SegmentOffsetType *fm = (SegmentOffsetType*) finalMessage; + fm[0] = OSSwapHostToBigInt32(domain); + fm[1] = OSSwapHostToBigInt32(event); + memcpy(&fm[2], message, messageLength); - SegmentOffsetType actualLength = messageLength + kHeaderLength; - - // for now, write a 0 for the length -- this will give clients the opportunity to not process an - // incomplete message - WriteOffsetAtOffset (pCount, 0); + SegmentOffsetType crc = CalculateCRC(finalMessage, messageSize); - // extend the overall write count by enough data to hold the message length and message - SetProducerCount (pCount + actualLength); + // write the length + WriteOffset(messageSize); - // write the data - WriteDataAtOffset (pCount + kHeaderLength, message, messageLength); + // write the crc + WriteOffset(crc); - // write the domain - WriteOffsetAtOffset (pCount + kDomainOffset, domain); + // write the data + WriteData (finalMessage, messageSize); - // write the event type - WriteOffsetAtOffset (pCount + kEventTypeOffset, event); - // write the data count - WriteOffsetAtOffset (pCount, actualLength); + SetProducerOffset(mDataPtr - mDataArea); } @@ -99,52 +117,53 @@ size_t SharedMemoryServer::GetSegmentSize () -SegmentOffsetType SharedMemoryServer::GetProducerCount () +SegmentOffsetType SharedMemoryServer::GetProducerOffset () { // the data is stored in the buffer in network byte order - u_int32_t pCount = *(u_int32_t*) mSegment; + u_int32_t pCount = OSSwapBigToHostInt32 (*(u_int32_t*) mSegment); return OSSwapHostToBigInt32 (pCount); } -void SharedMemoryServer::SetProducerCount (SegmentOffsetType producerCount) +void SharedMemoryServer::SetProducerOffset (SegmentOffsetType producerCount) { - *((u_int32_t*) mSegment) = OSSwapHostToBigInt32 (producerCount); + *((SegmentOffsetType*) mSegment) = OSSwapHostToBigInt32 (producerCount); } -void SharedMemoryServer::WriteOffsetAtOffset (SegmentOffsetType offset, SegmentOffsetType data) +void SharedMemoryServer::WriteOffset(SegmentOffsetType offset) { - // convert data to network byte order u_int8_t buffer[4]; - *((u_int32_t*) buffer) = OSSwapHostToBigInt32 (data); - - WriteDataAtOffset (offset, buffer, sizeof (buffer)); + *((u_int32_t*) buffer) = OSSwapHostToBigInt32(offset); + WriteData(buffer, 4); } -void SharedMemoryServer::WriteDataAtOffset (SegmentOffsetType offset, const void* data, SegmentOffsetType length) +void SharedMemoryServer::WriteData(const void* data, SegmentOffsetType length) { // figure out where in the buffer we actually need to write the data - SegmentOffsetType realOffset = offset % kPoolAvailableForData; - // figure out how many bytes we can write without overflowing the buffer - SegmentOffsetType bytesToEnd = kPoolAvailableForData - realOffset; + const u_int8_t* dp = (const u_int8_t*) data; + SegmentOffsetType bytesToEnd = mDataMax - mDataPtr; // figure out how many bytes we can write - SegmentOffsetType bytesToWrite = bytesToEnd < length ? bytesToEnd : length; - + SegmentOffsetType bytesToWrite = (length <= bytesToEnd) ? length : bytesToEnd; + // move the first part of the data, making sure to skip the producer pointer - memmove (mSegment + sizeof (SegmentOffsetType) + realOffset, data, bytesToWrite); + memcpy (mDataPtr, dp, bytesToWrite); + mDataPtr += bytesToWrite; + dp += bytesToWrite; // deduct the bytes just written length -= bytesToWrite; if (length != 0) // did we wrap around? { - memmove (mSegment + sizeof (SegmentOffsetType), ((u_int8_t*) data) + bytesToWrite, length); + mDataPtr = mDataArea; + memcpy (mDataPtr, dp, length); + mDataPtr += length; } }