⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 285865 in webkit


Ignore:
Timestamp:
Nov 16, 2021, 8:51:30 AM (5 years ago)
Author:
Chris Dumez
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):

Location:
trunk/Source/WebKit
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r285864 r285865  
     12021-11-16  Chris Dumez  <cdumez@apple.com>
     2
     3        Do some hardening in IPC::createMessageDecoder()
     4        https://bugs.webkit.org/show_bug.cgi?id=233148
     5        <rdar://75139294>
     6
     7        Reviewed by Darin Adler.
     8
     9        Do more bound validation insde createMessageDecoder() to make sure we stay within
     10        the bounds of our ReceiveBuffer.
     11
     12        Also, when the body is out of line, set `out_of_line.deallocate` to false since
     13        we are taking ownership of the memory and will vm_deallocate() it ourselves.
     14        Normally the sender (Connection::sendOutgoingMessage) sets that flag to false but
     15        it is better not to rely on the sender setting a particular flag.
     16
     17        * Platform/IPC/cocoa/ConnectionCocoa.mm:
     18        (IPC::createMessageDecoder):
     19        (IPC::Connection::receiveSourceEventHandler):
     20
    1212021-11-16  J Pascoe  <j_pascoe@apple.com>
    222
  • trunk/Source/WebKit/Platform/IPC/cocoa/ConnectionCocoa.mm

    r285138 r285865  
    409409}
    410410
    411 static std::unique_ptr<Decoder> createMessageDecoder(mach_msg_header_t* header)
    412 {
     411static std::unique_ptr<Decoder> createMessageDecoder(mach_msg_header_t* header, size_t bufferSize)
     412{
     413    if (UNLIKELY(header->msgh_size > bufferSize)) {
     414        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);
     415        ASSERT_NOT_REACHED();
     416        return nullptr;
     417    }
     418
    413419    if (!(header->msgh_bits & MACH_MSGH_BITS_COMPLEX)) {
    414420        // We have a simple message.
     
    427433    mach_msg_size_t numberOfPortDescriptors = body->msgh_descriptor_count;
    428434    ASSERT(numberOfPortDescriptors);
    429     if (!numberOfPortDescriptors)
     435    if (UNLIKELY(!numberOfPortDescriptors))
    430436        return nullptr;
     437
     438    auto sizeWithPortDescriptors = CheckedSize { sizeof(mach_msg_header_t) + sizeof(mach_msg_body_t) } + CheckedSize { numberOfPortDescriptors } * sizeof(mach_msg_port_descriptor_t);
     439    if (UNLIKELY(sizeWithPortDescriptors.hasOverflowed() || sizeWithPortDescriptors.value() > bufferSize)) {
     440        RELEASE_LOG_FAULT(IPC, "createMessageDecoder: Overflow when computing sizeWithPortDescriptors (numberOfPortDescriptors: %lu)", static_cast<unsigned long>(numberOfPortDescriptors));
     441        ASSERT_NOT_REACHED();
     442        return nullptr;
     443    }
    431444
    432445    uint8_t* descriptorData = reinterpret_cast<uint8_t*>(body + 1);
     
    446459            return nullptr;
    447460
    448         attachments[numberOfAttachments - i - 1] = Attachment(descriptor->port.name, descriptor->port.disposition);
     461        attachments[numberOfAttachments - i - 1] = Attachment { descriptor->port.name, descriptor->port.disposition };
    449462        descriptorData += sizeof(mach_msg_port_descriptor_t);
    450463    }
     
    458471        uint8_t* messageBody = static_cast<uint8_t*>(descriptor->out_of_line.address);
    459472        size_t messageBodySize = descriptor->out_of_line.size;
     473        descriptor->out_of_line.deallocate = false; // We are taking ownership of the memory.
    460474
    461475        return Decoder::create(messageBody, messageBodySize, [](const uint8_t* buffer, size_t length) {
     
    466480
    467481    uint8_t* messageBody = descriptorData;
    468     ASSERT(descriptorData >= reinterpret_cast<uint8_t*>(header));
    469     auto messageBodySize = CheckedSize { header->msgh_size } - static_cast<size_t>(descriptorData - reinterpret_cast<uint8_t*>(header));
     482    ASSERT((reinterpret_cast<uint8_t*>(header) + sizeWithPortDescriptors.value()) == messageBody);
     483    auto messageBodySize = header->msgh_size - sizeWithPortDescriptors;
    470484    if (UNLIKELY(messageBodySize.hasOverflowed())) {
    471         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)));
     485        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()));
    472486        ASSERT_NOT_REACHED();
    473487        return nullptr;
     
    538552    }
    539553
    540     std::unique_ptr<Decoder> decoder = createMessageDecoder(header);
     554    std::unique_ptr<Decoder> decoder = createMessageDecoder(header, buffer.size());
    541555    if (!decoder)
    542556        return;
Note: See TracChangeset for help on using the changeset viewer.