Title: [285865] trunk/Source/WebKit
Revision
285865
Author
cdu...@apple.com
Date
2021-11-16 08:51:30 -0800 (Tue, 16 Nov 2021)

Log Message

Do some hardening in IPC::createMessageDecoder()
https://bugs.webkit.org/show_bug.cgi?id=233148
<rdar://75139294>

Reviewed by Darin Adler.

Do more bound validation insde createMessageDecoder() to make sure we stay within
the bounds of our ReceiveBuffer.

Also, when the body is out of line, set `out_of_line.deallocate` to false since
we are taking ownership of the memory and will vm_deallocate() it ourselves.
Normally the sender (Connection::sendOutgoingMessage) sets that flag to false but
it is better not to rely on the sender setting a particular flag.

* Platform/IPC/cocoa/ConnectionCocoa.mm:
(IPC::createMessageDecoder):
(IPC::Connection::receiveSourceEventHandler):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (285864 => 285865)


--- trunk/Source/WebKit/ChangeLog	2021-11-16 16:47:40 UTC (rev 285864)
+++ trunk/Source/WebKit/ChangeLog	2021-11-16 16:51:30 UTC (rev 285865)
@@ -1,3 +1,23 @@
+2021-11-16  Chris Dumez  <cdu...@apple.com>
+
+        Do some hardening in IPC::createMessageDecoder()
+        https://bugs.webkit.org/show_bug.cgi?id=233148
+        <rdar://75139294>
+
+        Reviewed by Darin Adler.
+
+        Do more bound validation insde createMessageDecoder() to make sure we stay within
+        the bounds of our ReceiveBuffer.
+
+        Also, when the body is out of line, set `out_of_line.deallocate` to false since
+        we are taking ownership of the memory and will vm_deallocate() it ourselves.
+        Normally the sender (Connection::sendOutgoingMessage) sets that flag to false but
+        it is better not to rely on the sender setting a particular flag.
+
+        * Platform/IPC/cocoa/ConnectionCocoa.mm:
+        (IPC::createMessageDecoder):
+        (IPC::Connection::receiveSourceEventHandler):
+
 2021-11-16  J Pascoe  <j_pas...@apple.com>
 
         [WebAuthn] WebKitTestRunner/TWAPI lacks an entitlement and bundle identifier to use required [ASCAgent performAuthorizationRequestsForContext]

Modified: trunk/Source/WebKit/Platform/IPC/cocoa/ConnectionCocoa.mm (285864 => 285865)


--- trunk/Source/WebKit/Platform/IPC/cocoa/ConnectionCocoa.mm	2021-11-16 16:47:40 UTC (rev 285864)
+++ trunk/Source/WebKit/Platform/IPC/cocoa/ConnectionCocoa.mm	2021-11-16 16:51:30 UTC (rev 285865)
@@ -408,8 +408,14 @@
     sendOutgoingMessages();
 }
 
-static std::unique_ptr<Decoder> createMessageDecoder(mach_msg_header_t* header)
+static std::unique_ptr<Decoder> createMessageDecoder(mach_msg_header_t* header, size_t bufferSize)
 {
+    if (UNLIKELY(header->msgh_size > bufferSize)) {
+        RELEASE_LOG_FAULT(IPC, "createMessageDecoder: msgh_size is greater than bufferSize (header->msgh_size: %lu, bufferSize: %lu)", static_cast<unsigned long>(header->msgh_size), bufferSize);
+        ASSERT_NOT_REACHED();
+        return nullptr;
+    }
+
     if (!(header->msgh_bits & MACH_MSGH_BITS_COMPLEX)) {
         // We have a simple message.
         uint8_t* body = reinterpret_cast<uint8_t*>(header + 1);
@@ -426,9 +432,16 @@
     mach_msg_body_t* body = reinterpret_cast<mach_msg_body_t*>(header + 1);
     mach_msg_size_t numberOfPortDescriptors = body->msgh_descriptor_count;
     ASSERT(numberOfPortDescriptors);
-    if (!numberOfPortDescriptors)
+    if (UNLIKELY(!numberOfPortDescriptors))
         return nullptr;
 
+    auto sizeWithPortDescriptors = CheckedSize { sizeof(mach_msg_header_t) + sizeof(mach_msg_body_t) } + CheckedSize { numberOfPortDescriptors } * sizeof(mach_msg_port_descriptor_t);
+    if (UNLIKELY(sizeWithPortDescriptors.hasOverflowed() || sizeWithPortDescriptors.value() > bufferSize)) {
+        RELEASE_LOG_FAULT(IPC, "createMessageDecoder: Overflow when computing sizeWithPortDescriptors (numberOfPortDescriptors: %lu)", static_cast<unsigned long>(numberOfPortDescriptors));
+        ASSERT_NOT_REACHED();
+        return nullptr;
+    }
+
     uint8_t* descriptorData = reinterpret_cast<uint8_t*>(body + 1);
 
     // If the message body was sent out-of-line, don't treat the last descriptor
@@ -445,7 +458,7 @@
         if (descriptor->type.type != MACH_MSG_PORT_DESCRIPTOR)
             return nullptr;
 
-        attachments[numberOfAttachments - i - 1] = Attachment(descriptor->port.name, descriptor->port.disposition);
+        attachments[numberOfAttachments - i - 1] = Attachment { descriptor->port.name, descriptor->port.disposition };
         descriptorData += sizeof(mach_msg_port_descriptor_t);
     }
 
@@ -457,6 +470,7 @@
 
         uint8_t* messageBody = static_cast<uint8_t*>(descriptor->out_of_line.address);
         size_t messageBodySize = descriptor->out_of_line.size;
+        descriptor->out_of_line.deallocate = false; // We are taking ownership of the memory.
 
         return Decoder::create(messageBody, messageBodySize, [](const uint8_t* buffer, size_t length) {
             // FIXME: <rdar://problem/62086358> bufferDeallocator block ignores mach_msg_ool_descriptor_t->deallocate
@@ -465,10 +479,10 @@
     }
 
     uint8_t* messageBody = descriptorData;
-    ASSERT(descriptorData >= reinterpret_cast<uint8_t*>(header));
-    auto messageBodySize = CheckedSize { header->msgh_size } - static_cast<size_t>(descriptorData - reinterpret_cast<uint8_t*>(header));
+    ASSERT((reinterpret_cast<uint8_t*>(header) + sizeWithPortDescriptors.value()) == messageBody);
+    auto messageBodySize = header->msgh_size - sizeWithPortDescriptors;
     if (UNLIKELY(messageBodySize.hasOverflowed())) {
-        RELEASE_LOG_FAULT(IPC, "createMessageDecoder: Overflow when computing bodySize (header->msgh_size: %lu, (descriptorData - reinterpret_cast<uint8_t*>(header)): %lu)", static_cast<unsigned long>(header->msgh_size), static_cast<unsigned long>(descriptorData - reinterpret_cast<uint8_t*>(header)));
+        RELEASE_LOG_FAULT(IPC, "createMessageDecoder: Overflow when computing bodySize (header->msgh_size: %lu, sizeWithPortDescriptors: %lu)", static_cast<unsigned long>(header->msgh_size), static_cast<unsigned long>(sizeWithPortDescriptors.value()));
         ASSERT_NOT_REACHED();
         return nullptr;
     }
@@ -537,7 +551,7 @@
         return;
     }
 
-    std::unique_ptr<Decoder> decoder = createMessageDecoder(header);
+    std::unique_ptr<Decoder> decoder = createMessageDecoder(header, buffer.size());
     if (!decoder)
         return;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to