WebKit Bugzilla
Attachment 369289 Details for
Bug 197661
: Rename ConnectionMac.mm to ConnectionCocoa.mm since it is used on both macOS and iOS
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-197661-20190507090250.patch (text/plain), 76.43 KB, created by
Chris Dumez
on 2019-05-07 09:02:51 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Chris Dumez
Created:
2019-05-07 09:02:51 PDT
Size:
76.43 KB
patch
obsolete
>Subversion Revision: 245009 >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index 88ce45ee303d8a8e33e9b3d41a62ad179616778e..e86afe613cd98549413608bd409aa8f88c65c979 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,58 @@ >+2019-05-07 Chris Dumez <cdumez@apple.com> >+ >+ Rename ConnectionMac.mm to ConnectionCocoa.mm since it is used on both macOS and iOS >+ https://bugs.webkit.org/show_bug.cgi?id=197661 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * Platform/IPC/cocoa/ConnectionCocoa.mm: Renamed from Source/WebKit/Platform/IPC/mac/ConnectionMac.mm. >+ (IPC::ConnectionTerminationWatchdog::createConnectionTerminationWatchdog): >+ (IPC::ConnectionTerminationWatchdog::ConnectionTerminationWatchdog): >+ (IPC::ConnectionTerminationWatchdog::watchdogTimerFired): >+ (IPC::Connection::platformInvalidate): >+ (IPC::Connection::cancelReceiveSource): >+ (IPC::Connection::terminateSoon): >+ (IPC::Connection::platformInitialize): >+ (IPC::Connection::open): >+ (IPC::Connection::sendMessage): >+ (IPC::Connection::platformCanSendOutgoingMessages const): >+ (IPC::Connection::sendOutgoingMessage): >+ (IPC::Connection::initializeSendSource): >+ (IPC::Connection::resumeSendSource): >+ (IPC::createMessageDecoder): >+ (IPC::readFromMachPort): >+ (IPC::Connection::receiveSourceEventHandler): >+ (IPC::Connection::identifier const): >+ (IPC::Connection::getAuditToken): >+ (IPC::Connection::kill): >+ (IPC::AccessibilityProcessSuspendedNotification): >+ (IPC::Connection::willSendSyncMessage): >+ (IPC::Connection::didReceiveSyncReply): >+ (IPC::Connection::remoteProcessID const): >+ * Platform/IPC/cocoa/ImportanceAssertion.h: Renamed from Source/WebKit/Platform/IPC/mac/ImportanceAssertion.h. >+ (IPC::ImportanceAssertion::ImportanceAssertion): >+ (IPC::ImportanceAssertion::~ImportanceAssertion): >+ * Platform/IPC/cocoa/MachMessage.cpp: Renamed from Source/WebKit/Platform/IPC/mac/MachMessage.cpp. >+ (IPC::MachMessage::create): >+ (IPC::MachMessage::MachMessage): >+ (IPC::MachMessage::~MachMessage): >+ (IPC::MachMessage::messageSize): >+ (IPC::MachMessage::leakDescriptors): >+ * Platform/IPC/cocoa/MachMessage.h: Renamed from Source/WebKit/Platform/IPC/mac/MachMessage.h. >+ (IPC::MachMessage::size const): >+ (IPC::MachMessage::header): >+ (IPC::MachMessage::messageReceiverName const): >+ (IPC::MachMessage::messageName const): >+ * Platform/IPC/cocoa/MachPort.h: Renamed from Source/WebKit/Platform/IPC/mac/MachPort.h. >+ (IPC::MachPort::MachPort): >+ (IPC::MachPort::encode const): >+ (IPC::MachPort::decode): >+ (IPC::MachPort::port const): >+ (IPC::MachPort::disposition const): >+ * PlatformMac.cmake: >+ * SourcesCocoa.txt: >+ * WebKit.xcodeproj/project.pbxproj: >+ > 2019-05-07 Wenson Hsieh <wenson_hsieh@apple.com> > > [macOS] Avoid crashing the UI process when writing empty data to the pasteboard >diff --git a/Source/WebKit/Platform/IPC/cocoa/ConnectionCocoa.mm b/Source/WebKit/Platform/IPC/cocoa/ConnectionCocoa.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..e0a29f099ddd6cc972e5eec535d371c7cef491aa >--- /dev/null >+++ b/Source/WebKit/Platform/IPC/cocoa/ConnectionCocoa.mm >@@ -0,0 +1,654 @@ >+/* >+ * Copyright (C) 2010-2018 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#import "config.h" >+#import "Connection.h" >+ >+#import "DataReference.h" >+#import "ImportanceAssertion.h" >+#import "MachMessage.h" >+#import "MachPort.h" >+#import "MachUtilities.h" >+#import "WKCrashReporter.h" >+#import <WebCore/AXObjectCache.h> >+#import <mach/mach_error.h> >+#import <mach/vm_map.h> >+#import <sys/mman.h> >+#import <wtf/MachSendRight.h> >+#import <wtf/RunLoop.h> >+#import <wtf/spi/darwin/XPCSPI.h> >+ >+#if PLATFORM(IOS_FAMILY) >+#import "ProcessAssertion.h" >+#import <UIKit/UIAccessibility.h> >+ >+#if USE(APPLE_INTERNAL_SDK) >+#import <AXRuntime/AXDefines.h> >+#import <AXRuntime/AXNotificationConstants.h> >+#else >+#define kAXPidStatusChangedNotification 0 >+#endif >+ >+#endif >+ >+#if PLATFORM(MAC) >+ >+#if USE(APPLE_INTERNAL_SDK) >+#import <ApplicationServices/ApplicationServicesPriv.h> >+#else >+typedef enum { >+ AXSuspendStatusRunning = 0, >+ AXSuspendStatusSuspended, >+} AXSuspendStatus; >+#endif >+ >+extern "C" AXError _AXUIElementNotifyProcessSuspendStatus(AXSuspendStatus); >+ >+#endif // PLATFORM(MAC) >+ >+namespace IPC { >+ >+static const size_t inlineMessageMaxSize = 4096; >+ >+// Arbitrary message IDs that do not collide with Mach notification messages (used my initials). >+constexpr mach_msg_id_t inlineBodyMessageID = 0xdba0dba; >+constexpr mach_msg_id_t outOfLineBodyMessageID = 0xdba1dba; >+ >+// ConnectionTerminationWatchdog does two things: >+// 1) It sets a watchdog timer to kill the peered process. >+// 2) On iOS, make the process runnable for the duration of the watchdog >+// to ensure it has a chance to terminate cleanly. >+class ConnectionTerminationWatchdog { >+public: >+ static void createConnectionTerminationWatchdog(OSObjectPtr<xpc_connection_t>& xpcConnection, Seconds interval) >+ { >+ new ConnectionTerminationWatchdog(xpcConnection, interval); >+ } >+ >+private: >+ ConnectionTerminationWatchdog(OSObjectPtr<xpc_connection_t>& xpcConnection, Seconds interval) >+ : m_xpcConnection(xpcConnection) >+ , m_watchdogTimer(RunLoop::main(), this, &ConnectionTerminationWatchdog::watchdogTimerFired) >+#if PLATFORM(IOS_FAMILY) >+ , m_assertion(std::make_unique<WebKit::ProcessAndUIAssertion>(xpc_connection_get_pid(m_xpcConnection.get()), "ConnectionTerminationWatchdog"_s, WebKit::AssertionState::Background)) >+#endif >+ { >+ m_watchdogTimer.startOneShot(interval); >+ } >+ >+ void watchdogTimerFired() >+ { >+ xpc_connection_kill(m_xpcConnection.get(), SIGKILL); >+ delete this; >+ } >+ >+ OSObjectPtr<xpc_connection_t> m_xpcConnection; >+ RunLoop::Timer<ConnectionTerminationWatchdog> m_watchdogTimer; >+#if PLATFORM(IOS_FAMILY) >+ std::unique_ptr<WebKit::ProcessAndUIAssertion> m_assertion; >+#endif >+}; >+ >+void Connection::platformInvalidate() >+{ >+ if (!m_isConnected) { >+ if (m_sendPort) { >+ ASSERT(!m_isServer); >+ deallocateSendRightSafely(m_sendPort); >+ m_sendPort = MACH_PORT_NULL; >+ } >+ >+ if (m_receiveSource) { >+ // For a short period of time, when m_isServer is true and open() has been called, m_receiveSource has been initialized >+ // but m_isConnected has not been set to true yet. In this case, we need to cancel m_receiveSource instead of destroying >+ // m_receivePort ourselves. >+ ASSERT(m_isServer); >+ cancelReceiveSource(); >+ } >+ >+ if (m_receivePort) { >+ ASSERT(m_isServer); >+#if !PLATFORM(WATCHOS) >+ mach_port_unguard(mach_task_self(), m_receivePort, reinterpret_cast<mach_port_context_t>(this)); >+#endif >+ mach_port_mod_refs(mach_task_self(), m_receivePort, MACH_PORT_RIGHT_RECEIVE, -1); >+ m_receivePort = MACH_PORT_NULL; >+ } >+ >+ return; >+ } >+ >+ m_pendingOutgoingMachMessage = nullptr; >+ m_isInitializingSendSource = false; >+ m_isConnected = false; >+ >+ ASSERT(m_sendPort); >+ ASSERT(m_receivePort); >+ >+ // Unregister our ports. >+ dispatch_source_cancel(m_sendSource); >+ dispatch_release(m_sendSource); >+ m_sendSource = nullptr; >+ m_sendPort = MACH_PORT_NULL; >+ >+ cancelReceiveSource(); >+} >+ >+void Connection::cancelReceiveSource() >+{ >+ dispatch_source_cancel(m_receiveSource); >+ dispatch_release(m_receiveSource); >+ m_receiveSource = nullptr; >+ m_receivePort = MACH_PORT_NULL; >+} >+ >+void Connection::terminateSoon(Seconds interval) >+{ >+ if (m_xpcConnection) >+ ConnectionTerminationWatchdog::createConnectionTerminationWatchdog(m_xpcConnection, interval); >+} >+ >+void Connection::platformInitialize(Identifier identifier) >+{ >+ if (!MACH_PORT_VALID(identifier.port)) >+ return; >+ >+ if (m_isServer) { >+ m_receivePort = identifier.port; >+ m_sendPort = MACH_PORT_NULL; >+ >+#if !PLATFORM(WATCHOS) >+ mach_port_guard(mach_task_self(), m_receivePort, reinterpret_cast<mach_port_context_t>(this), true); >+#endif >+ } else { >+ m_receivePort = MACH_PORT_NULL; >+ m_sendPort = identifier.port; >+ } >+ >+ m_sendSource = nullptr; >+ m_receiveSource = nullptr; >+ >+ m_xpcConnection = identifier.xpcConnection; >+} >+ >+bool Connection::open() >+{ >+ if (m_isServer) { >+ ASSERT(m_receivePort); >+ ASSERT(!m_sendPort); >+ ASSERT(MACH_PORT_VALID(m_receivePort)); >+ } else { >+ ASSERT(!m_receivePort); >+ ASSERT(m_sendPort); >+ ASSERT(MACH_PORT_VALID(m_sendPort)); >+ >+ auto kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &m_receivePort); >+ if (kr != KERN_SUCCESS) { >+ LOG_ERROR("Could not allocate mach port, error %x: %s", kr, mach_error_string(kr)); >+ CRASH(); >+ } >+#if !PLATFORM(WATCHOS) >+ mach_port_guard(mach_task_self(), m_receivePort, reinterpret_cast<mach_port_context_t>(this), true); >+#endif >+ >+#if PLATFORM(MAC) >+ mach_port_set_attributes(mach_task_self(), m_receivePort, MACH_PORT_DENAP_RECEIVER, (mach_port_info_t)0, 0); >+#endif >+ >+ m_isConnected = true; >+ >+ // Send the initialize message, which contains a send right for the server to use. >+ auto encoder = std::make_unique<Encoder>("IPC", "InitializeConnection", 0); >+ encoder->encode(MachPort(m_receivePort, MACH_MSG_TYPE_MAKE_SEND)); >+ >+ initializeSendSource(); >+ >+ sendMessage(WTFMove(encoder), { }); >+ } >+ >+ // Change the message queue length for the receive port. >+ setMachPortQueueLength(m_receivePort, MACH_PORT_QLIMIT_LARGE); >+ >+ m_receiveSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, m_receivePort, 0, m_connectionQueue->dispatchQueue()); >+ dispatch_source_set_event_handler(m_receiveSource, [this, protectedThis = makeRef(*this)] { >+ receiveSourceEventHandler(); >+ }); >+ dispatch_source_set_cancel_handler(m_receiveSource, [protectedThis = makeRef(*this), receivePort = m_receivePort] { >+#if !PLATFORM(WATCHOS) >+ mach_port_unguard(mach_task_self(), receivePort, reinterpret_cast<mach_port_context_t>(protectedThis.ptr())); >+#endif >+ mach_port_mod_refs(mach_task_self(), receivePort, MACH_PORT_RIGHT_RECEIVE, -1); >+ }); >+ >+ ref(); >+ dispatch_async(m_connectionQueue->dispatchQueue(), ^{ >+ dispatch_resume(m_receiveSource); >+ >+ if (m_sendSource) >+ dispatch_resume(m_sendSource); >+ >+ deref(); >+ }); >+ >+ return true; >+} >+ >+bool Connection::sendMessage(std::unique_ptr<MachMessage> message) >+{ >+ ASSERT(message); >+ ASSERT(!m_pendingOutgoingMachMessage); >+ ASSERT(!m_isInitializingSendSource); >+ >+ // Send the message. >+ kern_return_t kr = mach_msg(message->header(), MACH_SEND_MSG | MACH_SEND_TIMEOUT | MACH_SEND_NOTIFY, message->size(), 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); >+ switch (kr) { >+ case MACH_MSG_SUCCESS: >+ // The kernel has already adopted the descriptors. >+ message->leakDescriptors(); >+ return true; >+ >+ case MACH_SEND_TIMED_OUT: >+ // We timed out, stash away the message for later. >+ m_pendingOutgoingMachMessage = WTFMove(message); >+ return false; >+ >+ case MACH_SEND_INVALID_DEST: >+ // The other end has disappeared, we'll get a dead name notification which will cause us to be invalidated. >+ return false; >+ >+ default: >+ WebKit::setCrashReportApplicationSpecificInformation((__bridge CFStringRef)[NSString stringWithFormat:@"Unhandled error code %x, message '%s::%s'", kr, message->messageReceiverName().data(), message->messageName().data()]); >+ CRASH(); >+ } >+} >+ >+bool Connection::platformCanSendOutgoingMessages() const >+{ >+ return !m_pendingOutgoingMachMessage && !m_isInitializingSendSource; >+} >+ >+bool Connection::sendOutgoingMessage(std::unique_ptr<Encoder> encoder) >+{ >+ ASSERT(!m_pendingOutgoingMachMessage && !m_isInitializingSendSource); >+ >+ auto attachments = encoder->releaseAttachments(); >+ >+ auto numberOfPortDescriptors = std::count_if(attachments.begin(), attachments.end(), [](auto& attachment) >+ { >+ return attachment.type() == Attachment::MachPortType; >+ }); >+ >+ bool messageBodyIsOOL = false; >+ auto messageSize = MachMessage::messageSize(encoder->bufferSize(), numberOfPortDescriptors, messageBodyIsOOL); >+ if (messageSize > inlineMessageMaxSize) { >+ messageBodyIsOOL = true; >+ messageSize = MachMessage::messageSize(0, numberOfPortDescriptors, messageBodyIsOOL); >+ } >+ >+ auto message = MachMessage::create(encoder->messageReceiverName().toString(), encoder->messageName().toString(), messageSize); >+ >+ auto* header = message->header(); >+ header->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0); >+ header->msgh_size = messageSize; >+ header->msgh_remote_port = m_sendPort; >+ header->msgh_local_port = MACH_PORT_NULL; >+ header->msgh_id = messageBodyIsOOL ? outOfLineBodyMessageID : inlineBodyMessageID; >+ >+ auto* messageData = reinterpret_cast<uint8_t*>(header + 1); >+ >+ bool isComplex = numberOfPortDescriptors || messageBodyIsOOL; >+ if (isComplex) { >+ header->msgh_bits |= MACH_MSGH_BITS_COMPLEX; >+ >+ auto* body = reinterpret_cast<mach_msg_body_t*>(messageData); >+ body->msgh_descriptor_count = numberOfPortDescriptors + messageBodyIsOOL; >+ messageData = reinterpret_cast<uint8_t*>(body + 1); >+ >+ auto getDescriptorAndAdvance = [](uint8_t*& data, std::size_t toAdvance) { >+ return reinterpret_cast<mach_msg_descriptor_t*>(std::exchange(data, data + toAdvance)); >+ }; >+ >+ for (auto& attachment : attachments) { >+ ASSERT(attachment.type() == Attachment::MachPortType); >+ if (attachment.type() == Attachment::MachPortType) { >+ auto* descriptor = getDescriptorAndAdvance(messageData, sizeof(mach_msg_port_descriptor_t)); >+ descriptor->port.name = attachment.port(); >+ descriptor->port.disposition = attachment.disposition(); >+ descriptor->port.type = MACH_MSG_PORT_DESCRIPTOR; >+ } >+ } >+ >+ if (messageBodyIsOOL) { >+ auto* descriptor = getDescriptorAndAdvance(messageData, sizeof(mach_msg_ool_descriptor_t)); >+ descriptor->out_of_line.address = encoder->buffer(); >+ descriptor->out_of_line.size = encoder->bufferSize(); >+ descriptor->out_of_line.copy = MACH_MSG_VIRTUAL_COPY; >+ descriptor->out_of_line.deallocate = false; >+ descriptor->out_of_line.type = MACH_MSG_OOL_DESCRIPTOR; >+ } >+ } >+ >+ // Copy the data if it is not being sent out-of-line. >+ if (!messageBodyIsOOL) >+ memcpy(messageData, encoder->buffer(), encoder->bufferSize()); >+ >+ ASSERT(m_sendPort); >+ ASSERT(MACH_PORT_VALID(m_sendPort)); >+ >+ return sendMessage(WTFMove(message)); >+} >+ >+void Connection::initializeSendSource() >+{ >+ m_sendSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_SEND, m_sendPort, DISPATCH_MACH_SEND_DEAD | DISPATCH_MACH_SEND_POSSIBLE, m_connectionQueue->dispatchQueue()); >+ m_isInitializingSendSource = true; >+ >+ dispatch_source_set_registration_handler(m_sendSource, [this, protectedThis = makeRef(*this)] { >+ if (!m_sendSource) >+ return; >+ m_isInitializingSendSource = false; >+ resumeSendSource(); >+ }); >+ dispatch_source_set_event_handler(m_sendSource, [this, protectedThis = makeRef(*this)] { >+ if (!m_sendSource) >+ return; >+ >+ unsigned long data = dispatch_source_get_data(m_sendSource); >+ >+ if (data & DISPATCH_MACH_SEND_DEAD) { >+ connectionDidClose(); >+ return; >+ } >+ >+ if (data & DISPATCH_MACH_SEND_POSSIBLE) { >+ // FIXME: Figure out why we get spurious DISPATCH_MACH_SEND_POSSIBLE events. >+ resumeSendSource(); >+ return; >+ } >+ }); >+ >+ ASSERT(MACH_PORT_VALID(m_sendPort)); >+ mach_port_t sendPort = m_sendPort; >+ dispatch_source_set_cancel_handler(m_sendSource, ^{ >+ // Release our send right. >+ deallocateSendRightSafely(sendPort); >+ }); >+} >+ >+void Connection::resumeSendSource() >+{ >+ ASSERT(!m_isInitializingSendSource); >+ if (m_pendingOutgoingMachMessage) >+ sendMessage(WTFMove(m_pendingOutgoingMachMessage)); >+ sendOutgoingMessages(); >+} >+ >+static std::unique_ptr<Decoder> createMessageDecoder(mach_msg_header_t* header) >+{ >+ if (!(header->msgh_bits & MACH_MSGH_BITS_COMPLEX)) { >+ // We have a simple message. >+ uint8_t* body = reinterpret_cast<uint8_t*>(header + 1); >+ size_t bodySize = header->msgh_size - sizeof(mach_msg_header_t); >+ >+ return std::make_unique<Decoder>(body, bodySize, nullptr, Vector<Attachment> { }); >+ } >+ >+ bool messageBodyIsOOL = header->msgh_id == outOfLineBodyMessageID; >+ >+ mach_msg_body_t* body = reinterpret_cast<mach_msg_body_t*>(header + 1); >+ mach_msg_size_t numDescriptors = body->msgh_descriptor_count; >+ ASSERT(numDescriptors); >+ >+ uint8_t* descriptorData = reinterpret_cast<uint8_t*>(body + 1); >+ >+ // If the message body was sent out-of-line, don't treat the last descriptor >+ // as an attachment, since it is really the message body. >+ if (messageBodyIsOOL) >+ --numDescriptors; >+ >+ // Build attachment list >+ Vector<Attachment> attachments(numDescriptors); >+ >+ for (mach_msg_size_t i = 0; i < numDescriptors; ++i) { >+ mach_msg_descriptor_t* descriptor = reinterpret_cast<mach_msg_descriptor_t*>(descriptorData); >+ ASSERT(descriptor->type.type == MACH_MSG_PORT_DESCRIPTOR); >+ if (descriptor->type.type != MACH_MSG_PORT_DESCRIPTOR) >+ return nullptr; >+ >+ attachments[numDescriptors - i - 1] = Attachment(descriptor->port.name, descriptor->port.disposition); >+ descriptorData += sizeof(mach_msg_port_descriptor_t); >+ } >+ >+ if (messageBodyIsOOL) { >+ mach_msg_descriptor_t* descriptor = reinterpret_cast<mach_msg_descriptor_t*>(descriptorData); >+ ASSERT(descriptor->type.type == MACH_MSG_OOL_DESCRIPTOR); >+ if (descriptor->type.type != MACH_MSG_OOL_DESCRIPTOR) >+ return nullptr; >+ >+ uint8_t* messageBody = static_cast<uint8_t*>(descriptor->out_of_line.address); >+ size_t messageBodySize = descriptor->out_of_line.size; >+ >+ return std::make_unique<Decoder>(messageBody, messageBodySize, [](const uint8_t* buffer, size_t length) { >+ vm_deallocate(mach_task_self(), reinterpret_cast<vm_address_t>(buffer), length); >+ }, WTFMove(attachments)); >+ } >+ >+ uint8_t* messageBody = descriptorData; >+ size_t messageBodySize = header->msgh_size - (descriptorData - reinterpret_cast<uint8_t*>(header)); >+ >+ return std::make_unique<Decoder>(messageBody, messageBodySize, nullptr, WTFMove(attachments)); >+} >+ >+// The receive buffer size should always include the maximum trailer size. >+static const size_t receiveBufferSize = inlineMessageMaxSize + MAX_TRAILER_SIZE; >+typedef Vector<char, receiveBufferSize> ReceiveBuffer; >+ >+static mach_msg_header_t* readFromMachPort(mach_port_t machPort, ReceiveBuffer& buffer) >+{ >+ ASSERT(MACH_PORT_VALID(machPort)); >+ >+ buffer.resize(receiveBufferSize); >+ >+ mach_msg_header_t* header = reinterpret_cast<mach_msg_header_t*>(buffer.data()); >+ kern_return_t kr = mach_msg(header, MACH_RCV_MSG | MACH_RCV_LARGE | MACH_RCV_TIMEOUT | MACH_RCV_VOUCHER, 0, buffer.size(), machPort, 0, MACH_PORT_NULL); >+ if (kr == MACH_RCV_TIMED_OUT) >+ return nullptr; >+ >+ if (kr == MACH_RCV_TOO_LARGE) { >+ // The message was too large, resize the buffer and try again. >+ buffer.resize(header->msgh_size + MAX_TRAILER_SIZE); >+ header = reinterpret_cast<mach_msg_header_t*>(buffer.data()); >+ >+ kr = mach_msg(header, MACH_RCV_MSG | MACH_RCV_LARGE | MACH_RCV_TIMEOUT | MACH_RCV_VOUCHER, 0, buffer.size(), machPort, 0, MACH_PORT_NULL); >+ ASSERT(kr != MACH_RCV_TOO_LARGE); >+ } >+ >+ if (kr != MACH_MSG_SUCCESS) { >+#if !ASSERT_DISABLED >+ WebKit::setCrashReportApplicationSpecificInformation((__bridge CFStringRef)[NSString stringWithFormat:@"Unhandled error code %x from mach_msg, receive port is %x", kr, machPort]); >+#endif >+ ASSERT_NOT_REACHED(); >+ return nullptr; >+ } >+ >+ return header; >+} >+ >+void Connection::receiveSourceEventHandler() >+{ >+ ReceiveBuffer buffer; >+ >+ ASSERT(MACH_PORT_VALID(m_receivePort)); >+ mach_msg_header_t* header = readFromMachPort(m_receivePort, buffer); >+ if (!header) >+ return; >+ >+ switch (header->msgh_id) { >+ case MACH_NOTIFY_NO_SENDERS: >+ ASSERT(m_isServer); >+ if (!m_sendPort) >+ connectionDidClose(); >+ return; >+ >+ case inlineBodyMessageID: >+ case outOfLineBodyMessageID: >+ break; >+ >+ case MACH_NOTIFY_SEND_ONCE: >+ default: >+ return; >+ } >+ >+ std::unique_ptr<Decoder> decoder = createMessageDecoder(header); >+ if (!decoder) >+ return; >+ >+#if PLATFORM(MAC) >+ decoder->setImportanceAssertion(std::make_unique<ImportanceAssertion>(header)); >+#endif >+ >+ if (decoder->messageReceiverName() == "IPC" && decoder->messageName() == "InitializeConnection") { >+ ASSERT(m_isServer); >+ ASSERT(!m_isConnected); >+ ASSERT(!m_sendPort); >+ >+ MachPort port; >+ if (!decoder->decode(port)) { >+ // FIXME: Disconnect. >+ return; >+ } >+ >+ m_sendPort = port.port(); >+ >+ if (m_sendPort) { >+ ASSERT(MACH_PORT_VALID(m_receivePort)); >+ mach_port_t previousNotificationPort = MACH_PORT_NULL; >+ auto kr = mach_port_request_notification(mach_task_self(), m_receivePort, MACH_NOTIFY_NO_SENDERS, 0, MACH_PORT_NULL, MACH_MSG_TYPE_MOVE_SEND_ONCE, &previousNotificationPort); >+ ASSERT(kr == KERN_SUCCESS); >+ if (kr != KERN_SUCCESS) { >+ // If mach_port_request_notification fails, 'previousNotificationPort' will be uninitialized. >+ LOG_ERROR("mach_port_request_notification failed: (%x) %s", kr, mach_error_string(kr)); >+ previousNotificationPort = MACH_PORT_NULL; >+ } >+ >+ if (previousNotificationPort != MACH_PORT_NULL) >+ deallocateSendRightSafely(previousNotificationPort); >+ >+ initializeSendSource(); >+ dispatch_resume(m_sendSource); >+ } >+ >+ m_isConnected = true; >+ >+ // Send any pending outgoing messages. >+ sendOutgoingMessages(); >+ >+ return; >+ } >+ >+#if !PLATFORM(IOS_FAMILY) >+ if (decoder->messageReceiverName() == "IPC" && decoder->messageName() == "SetExceptionPort") { >+ if (m_isServer) { >+ // Server connections aren't supposed to have their exception ports overridden. Treat this as an invalid message. >+ StringReference messageReceiverNameReference = decoder->messageReceiverName(); >+ String messageReceiverName(String(messageReceiverNameReference.data(), messageReceiverNameReference.size())); >+ StringReference messageNameReference = decoder->messageName(); >+ String messageName(String(messageNameReference.data(), messageNameReference.size())); >+ >+ RunLoop::main().dispatch([protectedThis = makeRef(*this), messageReceiverName = WTFMove(messageReceiverName), messageName = WTFMove(messageName)]() mutable { >+ protectedThis->dispatchDidReceiveInvalidMessage(messageReceiverName.utf8(), messageName.utf8()); >+ }); >+ return; >+ } >+ MachPort exceptionPort; >+ if (!decoder->decode(exceptionPort)) >+ return; >+ >+ setMachExceptionPort(exceptionPort.port()); >+ return; >+ } >+#endif >+ >+ processIncomingMessage(WTFMove(decoder)); >+} >+ >+IPC::Connection::Identifier Connection::identifier() const >+{ >+ return Identifier(m_isServer ? m_receivePort : m_sendPort, m_xpcConnection); >+} >+ >+Optional<audit_token_t> Connection::getAuditToken() >+{ >+ if (!m_xpcConnection) >+ return WTF::nullopt; >+ >+ audit_token_t auditToken; >+ xpc_connection_get_audit_token(m_xpcConnection.get(), &auditToken); >+ return WTFMove(auditToken); >+} >+ >+bool Connection::kill() >+{ >+ if (m_xpcConnection) { >+ xpc_connection_kill(m_xpcConnection.get(), SIGKILL); >+ m_wasKilled = true; >+ return true; >+ } >+ >+ return false; >+} >+ >+static void AccessibilityProcessSuspendedNotification(bool suspended) >+{ >+#if PLATFORM(MAC) >+ _AXUIElementNotifyProcessSuspendStatus(suspended ? AXSuspendStatusSuspended : AXSuspendStatusRunning); >+#elif PLATFORM(IOS_FAMILY) >+ UIAccessibilityPostNotification(kAXPidStatusChangedNotification, @{ @"pid" : @(getpid()), @"suspended" : @(suspended) }); >+#else >+ UNUSED_PARAM(suspended); >+#endif >+} >+ >+void Connection::willSendSyncMessage(OptionSet<SendSyncOption> sendSyncOptions) >+{ >+ if (sendSyncOptions.contains(IPC::SendSyncOption::InformPlatformProcessWillSuspend) && WebCore::AXObjectCache::accessibilityEnabled()) >+ AccessibilityProcessSuspendedNotification(true); >+} >+ >+void Connection::didReceiveSyncReply(OptionSet<SendSyncOption> sendSyncOptions) >+{ >+ if (sendSyncOptions.contains(IPC::SendSyncOption::InformPlatformProcessWillSuspend) && WebCore::AXObjectCache::accessibilityEnabled()) >+ AccessibilityProcessSuspendedNotification(false); >+} >+ >+pid_t Connection::remoteProcessID() const >+{ >+ if (!m_xpcConnection) >+ return 0; >+ >+ return xpc_connection_get_pid(m_xpcConnection.get()); >+} >+ >+} // namespace IPC >diff --git a/Source/WebKit/Platform/IPC/cocoa/ImportanceAssertion.h b/Source/WebKit/Platform/IPC/cocoa/ImportanceAssertion.h >new file mode 100644 >index 0000000000000000000000000000000000000000..62bd8854475a02a84b32477e0dbf929e1748de53 >--- /dev/null >+++ b/Source/WebKit/Platform/IPC/cocoa/ImportanceAssertion.h >@@ -0,0 +1,63 @@ >+/* >+ * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if PLATFORM(MAC) >+ >+#include <mach/message.h> >+ >+namespace IPC { >+ >+class ImportanceAssertion { >+ WTF_MAKE_FAST_ALLOCATED; >+ WTF_MAKE_NONCOPYABLE(ImportanceAssertion); >+ >+public: >+ explicit ImportanceAssertion(mach_msg_header_t* header) >+ : m_voucher(0) >+ { >+ if (MACH_MSGH_BITS_HAS_VOUCHER(header->msgh_bits)) { >+ m_voucher = header->msgh_voucher_port; >+ header->msgh_voucher_port = MACH_VOUCHER_NULL; >+ header->msgh_bits &= ~(MACH_MSGH_BITS_VOUCHER_MASK | MACH_MSGH_BITS_RAISEIMP); >+ } >+ } >+ >+ ~ImportanceAssertion() >+ { >+ if (m_voucher) { >+ kern_return_t kr = mach_voucher_deallocate(m_voucher); >+ ASSERT_UNUSED(kr, !kr); >+ } >+ } >+ >+private: >+ mach_voucher_t m_voucher; >+}; >+ >+} >+ >+#endif // PLATFORM(MAC) >diff --git a/Source/WebKit/Platform/IPC/cocoa/MachMessage.cpp b/Source/WebKit/Platform/IPC/cocoa/MachMessage.cpp >new file mode 100644 >index 0000000000000000000000000000000000000000..ec84c96a139af805f13f07ac7cbe024b0f53da23 >--- /dev/null >+++ b/Source/WebKit/Platform/IPC/cocoa/MachMessage.cpp >@@ -0,0 +1,74 @@ >+/* >+ * Copyright (C) 2016 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#include "config.h" >+#include "MachMessage.h" >+ >+#if PLATFORM(COCOA) >+ >+#include <mach/mach.h> >+ >+namespace IPC { >+ >+std::unique_ptr<MachMessage> MachMessage::create(CString&& messageReceiverName, CString&& messageName, size_t size) >+{ >+ void* memory = WTF::fastZeroedMalloc(sizeof(MachMessage) + size); >+ return std::unique_ptr<MachMessage> { new (NotNull, memory) MachMessage { WTFMove(messageReceiverName), WTFMove(messageName), size } }; >+} >+ >+MachMessage::MachMessage(CString&& messageReceiverName, CString&& messageName, size_t size) >+ : m_messageReceiverName(WTFMove(messageReceiverName)) >+ , m_messageName(WTFMove(messageName)) >+ , m_size { size } >+{ >+} >+ >+MachMessage::~MachMessage() >+{ >+ if (m_shouldFreeDescriptors) >+ ::mach_msg_destroy(header()); >+} >+ >+size_t MachMessage::messageSize(size_t bodySize, size_t portDescriptorCount, size_t memoryDescriptorCount) >+{ >+ size_t messageSize = sizeof(mach_msg_header_t) + bodySize; >+ >+ if (portDescriptorCount || memoryDescriptorCount) { >+ messageSize += sizeof(mach_msg_body_t); >+ messageSize += (portDescriptorCount * sizeof(mach_msg_port_descriptor_t)); >+ messageSize += (memoryDescriptorCount * sizeof(mach_msg_ool_descriptor_t)); >+ } >+ >+ return round_msg(messageSize); >+} >+ >+void MachMessage::leakDescriptors() >+{ >+ m_shouldFreeDescriptors = false; >+} >+ >+} >+ >+#endif // PLATFORM(COCOA) >diff --git a/Source/WebKit/Platform/IPC/cocoa/MachMessage.h b/Source/WebKit/Platform/IPC/cocoa/MachMessage.h >new file mode 100644 >index 0000000000000000000000000000000000000000..d0131c7f0d3efa38af4054e276d4fc286c93442c >--- /dev/null >+++ b/Source/WebKit/Platform/IPC/cocoa/MachMessage.h >@@ -0,0 +1,64 @@ >+/* >+ * Copyright (C) 2016 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#if PLATFORM(COCOA) >+ >+#include <mach/message.h> >+#include <memory> >+#include <wtf/text/CString.h> >+ >+namespace IPC { >+ >+class MachMessage { >+ WTF_MAKE_FAST_ALLOCATED; >+public: >+ static std::unique_ptr<MachMessage> create(CString&& messageReceiverName, CString&& messageName, size_t); >+ ~MachMessage(); >+ >+ static size_t messageSize(size_t bodySize, size_t portDescriptorCount, size_t memoryDescriptorCount); >+ >+ size_t size() const { return m_size; } >+ mach_msg_header_t* header() { return m_messageHeader; } >+ >+ void leakDescriptors(); >+ >+ const CString& messageReceiverName() const { return m_messageReceiverName; } >+ const CString& messageName() const { return m_messageName; } >+ >+private: >+ MachMessage(CString&& messageReceiverName, CString&& messageName, size_t); >+ >+ CString m_messageReceiverName; >+ CString m_messageName; >+ size_t m_size; >+ bool m_shouldFreeDescriptors { true }; >+ mach_msg_header_t m_messageHeader[]; >+}; >+ >+} >+ >+#endif // PLATFORM(COCOA) >diff --git a/Source/WebKit/Platform/IPC/cocoa/MachPort.h b/Source/WebKit/Platform/IPC/cocoa/MachPort.h >new file mode 100644 >index 0000000000000000000000000000000000000000..0d0c364082377eca36e33b8fcb851cb67590ac4f >--- /dev/null >+++ b/Source/WebKit/Platform/IPC/cocoa/MachPort.h >@@ -0,0 +1,72 @@ >+/* >+ * Copyright (C) 2010 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >+ * THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "Attachment.h" >+#include "Decoder.h" >+#include "Encoder.h" >+ >+namespace IPC { >+ >+class MachPort { >+public: >+ MachPort() >+ : m_port(MACH_PORT_NULL) >+ , m_disposition(0) >+ { >+ } >+ >+ MachPort(mach_port_name_t port, mach_msg_type_name_t disposition) >+ : m_port(port) >+ , m_disposition(disposition) >+ { >+ } >+ >+ void encode(Encoder& encoder) const >+ { >+ encoder << Attachment(m_port, m_disposition); >+ } >+ >+ static bool decode(Decoder& decoder, MachPort& p) >+ { >+ Attachment attachment; >+ if (!decoder.decode(attachment)) >+ return false; >+ >+ p.m_port = attachment.port(); >+ p.m_disposition = attachment.disposition(); >+ return true; >+ } >+ >+ mach_port_name_t port() const { return m_port; } >+ mach_msg_type_name_t disposition() const { return m_disposition; } >+ >+private: >+ mach_port_name_t m_port; >+ mach_msg_type_name_t m_disposition; >+}; >+ >+} // namespace IPC >diff --git a/Source/WebKit/Platform/IPC/mac/ConnectionMac.mm b/Source/WebKit/Platform/IPC/mac/ConnectionMac.mm >deleted file mode 100644 >index dc5f11c0cacd9a7d872988624cb29453013235ba..0000000000000000000000000000000000000000 >--- a/Source/WebKit/Platform/IPC/mac/ConnectionMac.mm >+++ /dev/null >@@ -1,654 +0,0 @@ >-/* >- * Copyright (C) 2010-2018 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >- * THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#import "config.h" >-#import "Connection.h" >- >-#import "DataReference.h" >-#import "ImportanceAssertion.h" >-#import "MachMessage.h" >-#import "MachPort.h" >-#import "MachUtilities.h" >-#import "WKCrashReporter.h" >-#import <WebCore/AXObjectCache.h> >-#import <mach/mach_error.h> >-#import <mach/vm_map.h> >-#import <sys/mman.h> >-#import <wtf/MachSendRight.h> >-#import <wtf/RunLoop.h> >-#import <wtf/spi/darwin/XPCSPI.h> >- >-#if PLATFORM(IOS_FAMILY) >-#import "ProcessAssertion.h" >-#import <UIKit/UIAccessibility.h> >- >-#if USE(APPLE_INTERNAL_SDK) >-#import <AXRuntime/AXDefines.h> >-#import <AXRuntime/AXNotificationConstants.h> >-#else >-#define kAXPidStatusChangedNotification 0 >-#endif >- >-#endif >- >-#if PLATFORM(MAC) >- >-#if USE(APPLE_INTERNAL_SDK) >-#import <ApplicationServices/ApplicationServicesPriv.h> >-#else >-typedef enum { >- AXSuspendStatusRunning = 0, >- AXSuspendStatusSuspended, >-} AXSuspendStatus; >-#endif >- >-extern "C" AXError _AXUIElementNotifyProcessSuspendStatus(AXSuspendStatus); >- >-#endif // PLATFORM(MAC) >- >-namespace IPC { >- >-static const size_t inlineMessageMaxSize = 4096; >- >-// Arbitrary message IDs that do not collide with Mach notification messages (used my initials). >-constexpr mach_msg_id_t inlineBodyMessageID = 0xdba0dba; >-constexpr mach_msg_id_t outOfLineBodyMessageID = 0xdba1dba; >- >-// ConnectionTerminationWatchdog does two things: >-// 1) It sets a watchdog timer to kill the peered process. >-// 2) On iOS, make the process runnable for the duration of the watchdog >-// to ensure it has a chance to terminate cleanly. >-class ConnectionTerminationWatchdog { >-public: >- static void createConnectionTerminationWatchdog(OSObjectPtr<xpc_connection_t>& xpcConnection, Seconds interval) >- { >- new ConnectionTerminationWatchdog(xpcConnection, interval); >- } >- >-private: >- ConnectionTerminationWatchdog(OSObjectPtr<xpc_connection_t>& xpcConnection, Seconds interval) >- : m_xpcConnection(xpcConnection) >- , m_watchdogTimer(RunLoop::main(), this, &ConnectionTerminationWatchdog::watchdogTimerFired) >-#if PLATFORM(IOS_FAMILY) >- , m_assertion(std::make_unique<WebKit::ProcessAndUIAssertion>(xpc_connection_get_pid(m_xpcConnection.get()), "ConnectionTerminationWatchdog"_s, WebKit::AssertionState::Background)) >-#endif >- { >- m_watchdogTimer.startOneShot(interval); >- } >- >- void watchdogTimerFired() >- { >- xpc_connection_kill(m_xpcConnection.get(), SIGKILL); >- delete this; >- } >- >- OSObjectPtr<xpc_connection_t> m_xpcConnection; >- RunLoop::Timer<ConnectionTerminationWatchdog> m_watchdogTimer; >-#if PLATFORM(IOS_FAMILY) >- std::unique_ptr<WebKit::ProcessAndUIAssertion> m_assertion; >-#endif >-}; >- >-void Connection::platformInvalidate() >-{ >- if (!m_isConnected) { >- if (m_sendPort) { >- ASSERT(!m_isServer); >- deallocateSendRightSafely(m_sendPort); >- m_sendPort = MACH_PORT_NULL; >- } >- >- if (m_receiveSource) { >- // For a short period of time, when m_isServer is true and open() has been called, m_receiveSource has been initialized >- // but m_isConnected has not been set to true yet. In this case, we need to cancel m_receiveSource instead of destroying >- // m_receivePort ourselves. >- ASSERT(m_isServer); >- cancelReceiveSource(); >- } >- >- if (m_receivePort) { >- ASSERT(m_isServer); >-#if !PLATFORM(WATCHOS) >- mach_port_unguard(mach_task_self(), m_receivePort, reinterpret_cast<mach_port_context_t>(this)); >-#endif >- mach_port_mod_refs(mach_task_self(), m_receivePort, MACH_PORT_RIGHT_RECEIVE, -1); >- m_receivePort = MACH_PORT_NULL; >- } >- >- return; >- } >- >- m_pendingOutgoingMachMessage = nullptr; >- m_isInitializingSendSource = false; >- m_isConnected = false; >- >- ASSERT(m_sendPort); >- ASSERT(m_receivePort); >- >- // Unregister our ports. >- dispatch_source_cancel(m_sendSource); >- dispatch_release(m_sendSource); >- m_sendSource = nullptr; >- m_sendPort = MACH_PORT_NULL; >- >- cancelReceiveSource(); >-} >- >-void Connection::cancelReceiveSource() >-{ >- dispatch_source_cancel(m_receiveSource); >- dispatch_release(m_receiveSource); >- m_receiveSource = nullptr; >- m_receivePort = MACH_PORT_NULL; >-} >- >-void Connection::terminateSoon(Seconds interval) >-{ >- if (m_xpcConnection) >- ConnectionTerminationWatchdog::createConnectionTerminationWatchdog(m_xpcConnection, interval); >-} >- >-void Connection::platformInitialize(Identifier identifier) >-{ >- if (!MACH_PORT_VALID(identifier.port)) >- return; >- >- if (m_isServer) { >- m_receivePort = identifier.port; >- m_sendPort = MACH_PORT_NULL; >- >-#if !PLATFORM(WATCHOS) >- mach_port_guard(mach_task_self(), m_receivePort, reinterpret_cast<mach_port_context_t>(this), true); >-#endif >- } else { >- m_receivePort = MACH_PORT_NULL; >- m_sendPort = identifier.port; >- } >- >- m_sendSource = nullptr; >- m_receiveSource = nullptr; >- >- m_xpcConnection = identifier.xpcConnection; >-} >- >-bool Connection::open() >-{ >- if (m_isServer) { >- ASSERT(m_receivePort); >- ASSERT(!m_sendPort); >- ASSERT(MACH_PORT_VALID(m_receivePort)); >- } else { >- ASSERT(!m_receivePort); >- ASSERT(m_sendPort); >- ASSERT(MACH_PORT_VALID(m_sendPort)); >- >- auto kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &m_receivePort); >- if (kr != KERN_SUCCESS) { >- LOG_ERROR("Could not allocate mach port, error %x: %s", kr, mach_error_string(kr)); >- CRASH(); >- } >-#if !PLATFORM(WATCHOS) >- mach_port_guard(mach_task_self(), m_receivePort, reinterpret_cast<mach_port_context_t>(this), true); >-#endif >- >-#if PLATFORM(MAC) >- mach_port_set_attributes(mach_task_self(), m_receivePort, MACH_PORT_DENAP_RECEIVER, (mach_port_info_t)0, 0); >-#endif >- >- m_isConnected = true; >- >- // Send the initialize message, which contains a send right for the server to use. >- auto encoder = std::make_unique<Encoder>("IPC", "InitializeConnection", 0); >- encoder->encode(MachPort(m_receivePort, MACH_MSG_TYPE_MAKE_SEND)); >- >- initializeSendSource(); >- >- sendMessage(WTFMove(encoder), { }); >- } >- >- // Change the message queue length for the receive port. >- setMachPortQueueLength(m_receivePort, MACH_PORT_QLIMIT_LARGE); >- >- RefPtr<Connection> connection(this); >- m_receiveSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, m_receivePort, 0, m_connectionQueue->dispatchQueue()); >- dispatch_source_set_event_handler(m_receiveSource, [connection] { >- connection->receiveSourceEventHandler(); >- }); >- dispatch_source_set_cancel_handler(m_receiveSource, [connection, receivePort = m_receivePort] { >-#if PLATFORM(WATCHOS) >- UNUSED_PARAM(connection); >-#else >- mach_port_unguard(mach_task_self(), receivePort, reinterpret_cast<mach_port_context_t>(connection.get())); >-#endif >- mach_port_mod_refs(mach_task_self(), receivePort, MACH_PORT_RIGHT_RECEIVE, -1); >- }); >- >- ref(); >- dispatch_async(m_connectionQueue->dispatchQueue(), ^{ >- dispatch_resume(m_receiveSource); >- >- if (m_sendSource) >- dispatch_resume(m_sendSource); >- >- deref(); >- }); >- >- return true; >-} >- >-bool Connection::sendMessage(std::unique_ptr<MachMessage> message) >-{ >- ASSERT(message); >- ASSERT(!m_pendingOutgoingMachMessage); >- ASSERT(!m_isInitializingSendSource); >- >- // Send the message. >- kern_return_t kr = mach_msg(message->header(), MACH_SEND_MSG | MACH_SEND_TIMEOUT | MACH_SEND_NOTIFY, message->size(), 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); >- switch (kr) { >- case MACH_MSG_SUCCESS: >- // The kernel has already adopted the descriptors. >- message->leakDescriptors(); >- return true; >- >- case MACH_SEND_TIMED_OUT: >- // We timed out, stash away the message for later. >- m_pendingOutgoingMachMessage = WTFMove(message); >- return false; >- >- case MACH_SEND_INVALID_DEST: >- // The other end has disappeared, we'll get a dead name notification which will cause us to be invalidated. >- return false; >- >- default: >- WebKit::setCrashReportApplicationSpecificInformation((__bridge CFStringRef)[NSString stringWithFormat:@"Unhandled error code %x, message '%s::%s'", kr, message->messageReceiverName().data(), message->messageName().data()]); >- CRASH(); >- } >-} >- >-bool Connection::platformCanSendOutgoingMessages() const >-{ >- return !m_pendingOutgoingMachMessage && !m_isInitializingSendSource; >-} >- >-bool Connection::sendOutgoingMessage(std::unique_ptr<Encoder> encoder) >-{ >- ASSERT(!m_pendingOutgoingMachMessage && !m_isInitializingSendSource); >- >- auto attachments = encoder->releaseAttachments(); >- >- auto numberOfPortDescriptors = std::count_if(attachments.begin(), attachments.end(), [](auto& attachment) { return attachment.type() == Attachment::MachPortType; }); >- bool messageBodyIsOOL = false; >- auto messageSize = MachMessage::messageSize(encoder->bufferSize(), numberOfPortDescriptors, messageBodyIsOOL); >- if (messageSize > inlineMessageMaxSize) { >- messageBodyIsOOL = true; >- messageSize = MachMessage::messageSize(0, numberOfPortDescriptors, messageBodyIsOOL); >- } >- >- auto message = MachMessage::create(encoder->messageReceiverName().toString(), encoder->messageName().toString(), messageSize); >- >- auto* header = message->header(); >- header->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0); >- header->msgh_size = messageSize; >- header->msgh_remote_port = m_sendPort; >- header->msgh_local_port = MACH_PORT_NULL; >- header->msgh_id = messageBodyIsOOL ? outOfLineBodyMessageID : inlineBodyMessageID; >- >- auto* messageData = reinterpret_cast<uint8_t*>(header + 1); >- >- bool isComplex = numberOfPortDescriptors || messageBodyIsOOL; >- if (isComplex) { >- header->msgh_bits |= MACH_MSGH_BITS_COMPLEX; >- >- auto* body = reinterpret_cast<mach_msg_body_t*>(messageData); >- body->msgh_descriptor_count = numberOfPortDescriptors + messageBodyIsOOL; >- messageData = reinterpret_cast<uint8_t*>(body + 1); >- >- auto getDescriptorAndAdvance = [](uint8_t*& data, std::size_t toAdvance) { >- return reinterpret_cast<mach_msg_descriptor_t*>(std::exchange(data, data + toAdvance)); >- }; >- >- for (auto& attachment : attachments) { >- ASSERT(attachment.type() == Attachment::MachPortType); >- if (attachment.type() == Attachment::MachPortType) { >- auto* descriptor = getDescriptorAndAdvance(messageData, sizeof(mach_msg_port_descriptor_t)); >- descriptor->port.name = attachment.port(); >- descriptor->port.disposition = attachment.disposition(); >- descriptor->port.type = MACH_MSG_PORT_DESCRIPTOR; >- } >- } >- >- if (messageBodyIsOOL) { >- auto* descriptor = getDescriptorAndAdvance(messageData, sizeof(mach_msg_ool_descriptor_t)); >- descriptor->out_of_line.address = encoder->buffer(); >- descriptor->out_of_line.size = encoder->bufferSize(); >- descriptor->out_of_line.copy = MACH_MSG_VIRTUAL_COPY; >- descriptor->out_of_line.deallocate = false; >- descriptor->out_of_line.type = MACH_MSG_OOL_DESCRIPTOR; >- } >- } >- >- // Copy the data if it is not being sent out-of-line. >- if (!messageBodyIsOOL) >- memcpy(messageData, encoder->buffer(), encoder->bufferSize()); >- >- ASSERT(m_sendPort); >- ASSERT(MACH_PORT_VALID(m_sendPort)); >- >- return sendMessage(WTFMove(message)); >-} >- >-void Connection::initializeSendSource() >-{ >- m_sendSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_SEND, m_sendPort, DISPATCH_MACH_SEND_DEAD | DISPATCH_MACH_SEND_POSSIBLE, m_connectionQueue->dispatchQueue()); >- m_isInitializingSendSource = true; >- >- RefPtr<Connection> connection(this); >- dispatch_source_set_registration_handler(m_sendSource, [connection] { >- if (!connection->m_sendSource) >- return; >- connection->m_isInitializingSendSource = false; >- connection->resumeSendSource(); >- }); >- dispatch_source_set_event_handler(m_sendSource, [connection] { >- if (!connection->m_sendSource) >- return; >- >- unsigned long data = dispatch_source_get_data(connection->m_sendSource); >- >- if (data & DISPATCH_MACH_SEND_DEAD) { >- connection->connectionDidClose(); >- return; >- } >- >- if (data & DISPATCH_MACH_SEND_POSSIBLE) { >- // FIXME: Figure out why we get spurious DISPATCH_MACH_SEND_POSSIBLE events. >- connection->resumeSendSource(); >- return; >- } >- }); >- >- ASSERT(MACH_PORT_VALID(m_sendPort)); >- mach_port_t sendPort = m_sendPort; >- dispatch_source_set_cancel_handler(m_sendSource, ^{ >- // Release our send right. >- deallocateSendRightSafely(sendPort); >- }); >-} >- >-void Connection::resumeSendSource() >-{ >- ASSERT(!m_isInitializingSendSource); >- if (m_pendingOutgoingMachMessage) >- sendMessage(WTFMove(m_pendingOutgoingMachMessage)); >- sendOutgoingMessages(); >-} >- >-static std::unique_ptr<Decoder> createMessageDecoder(mach_msg_header_t* header) >-{ >- if (!(header->msgh_bits & MACH_MSGH_BITS_COMPLEX)) { >- // We have a simple message. >- uint8_t* body = reinterpret_cast<uint8_t*>(header + 1); >- size_t bodySize = header->msgh_size - sizeof(mach_msg_header_t); >- >- return std::make_unique<Decoder>(body, bodySize, nullptr, Vector<Attachment> { }); >- } >- >- bool messageBodyIsOOL = header->msgh_id == outOfLineBodyMessageID; >- >- mach_msg_body_t* body = reinterpret_cast<mach_msg_body_t*>(header + 1); >- mach_msg_size_t numDescriptors = body->msgh_descriptor_count; >- ASSERT(numDescriptors); >- >- uint8_t* descriptorData = reinterpret_cast<uint8_t*>(body + 1); >- >- // If the message body was sent out-of-line, don't treat the last descriptor >- // as an attachment, since it is really the message body. >- if (messageBodyIsOOL) >- --numDescriptors; >- >- // Build attachment list >- Vector<Attachment> attachments(numDescriptors); >- >- for (mach_msg_size_t i = 0; i < numDescriptors; ++i) { >- mach_msg_descriptor_t* descriptor = reinterpret_cast<mach_msg_descriptor_t*>(descriptorData); >- ASSERT(descriptor->type.type == MACH_MSG_PORT_DESCRIPTOR); >- if (descriptor->type.type != MACH_MSG_PORT_DESCRIPTOR) >- return nullptr; >- >- attachments[numDescriptors - i - 1] = Attachment(descriptor->port.name, descriptor->port.disposition); >- descriptorData += sizeof(mach_msg_port_descriptor_t); >- } >- >- if (messageBodyIsOOL) { >- mach_msg_descriptor_t* descriptor = reinterpret_cast<mach_msg_descriptor_t*>(descriptorData); >- ASSERT(descriptor->type.type == MACH_MSG_OOL_DESCRIPTOR); >- if (descriptor->type.type != MACH_MSG_OOL_DESCRIPTOR) >- return nullptr; >- >- uint8_t* messageBody = static_cast<uint8_t*>(descriptor->out_of_line.address); >- size_t messageBodySize = descriptor->out_of_line.size; >- >- return std::make_unique<Decoder>(messageBody, messageBodySize, [](const uint8_t* buffer, size_t length) { >- vm_deallocate(mach_task_self(), reinterpret_cast<vm_address_t>(buffer), length); >- }, WTFMove(attachments)); >- } >- >- uint8_t* messageBody = descriptorData; >- size_t messageBodySize = header->msgh_size - (descriptorData - reinterpret_cast<uint8_t*>(header)); >- >- return std::make_unique<Decoder>(messageBody, messageBodySize, nullptr, WTFMove(attachments)); >-} >- >-// The receive buffer size should always include the maximum trailer size. >-static const size_t receiveBufferSize = inlineMessageMaxSize + MAX_TRAILER_SIZE; >-typedef Vector<char, receiveBufferSize> ReceiveBuffer; >- >-static mach_msg_header_t* readFromMachPort(mach_port_t machPort, ReceiveBuffer& buffer) >-{ >- ASSERT(MACH_PORT_VALID(machPort)); >- >- buffer.resize(receiveBufferSize); >- >- mach_msg_header_t* header = reinterpret_cast<mach_msg_header_t*>(buffer.data()); >- kern_return_t kr = mach_msg(header, MACH_RCV_MSG | MACH_RCV_LARGE | MACH_RCV_TIMEOUT | MACH_RCV_VOUCHER, 0, buffer.size(), machPort, 0, MACH_PORT_NULL); >- if (kr == MACH_RCV_TIMED_OUT) >- return nullptr; >- >- if (kr == MACH_RCV_TOO_LARGE) { >- // The message was too large, resize the buffer and try again. >- buffer.resize(header->msgh_size + MAX_TRAILER_SIZE); >- header = reinterpret_cast<mach_msg_header_t*>(buffer.data()); >- >- kr = mach_msg(header, MACH_RCV_MSG | MACH_RCV_LARGE | MACH_RCV_TIMEOUT | MACH_RCV_VOUCHER, 0, buffer.size(), machPort, 0, MACH_PORT_NULL); >- ASSERT(kr != MACH_RCV_TOO_LARGE); >- } >- >- if (kr != MACH_MSG_SUCCESS) { >-#if !ASSERT_DISABLED >- WebKit::setCrashReportApplicationSpecificInformation((__bridge CFStringRef)[NSString stringWithFormat:@"Unhandled error code %x from mach_msg, receive port is %x", kr, machPort]); >-#endif >- ASSERT_NOT_REACHED(); >- return nullptr; >- } >- >- return header; >-} >- >-void Connection::receiveSourceEventHandler() >-{ >- ReceiveBuffer buffer; >- >- ASSERT(MACH_PORT_VALID(m_receivePort)); >- mach_msg_header_t* header = readFromMachPort(m_receivePort, buffer); >- if (!header) >- return; >- >- switch (header->msgh_id) { >- case MACH_NOTIFY_NO_SENDERS: >- ASSERT(m_isServer); >- if (!m_sendPort) >- connectionDidClose(); >- return; >- >- case inlineBodyMessageID: >- case outOfLineBodyMessageID: >- break; >- >- case MACH_NOTIFY_SEND_ONCE: >- default: >- return; >- } >- >- std::unique_ptr<Decoder> decoder = createMessageDecoder(header); >- if (!decoder) >- return; >- >-#if PLATFORM(MAC) >- decoder->setImportanceAssertion(std::make_unique<ImportanceAssertion>(header)); >-#endif >- >- if (decoder->messageReceiverName() == "IPC" && decoder->messageName() == "InitializeConnection") { >- ASSERT(m_isServer); >- ASSERT(!m_isConnected); >- ASSERT(!m_sendPort); >- >- MachPort port; >- if (!decoder->decode(port)) { >- // FIXME: Disconnect. >- return; >- } >- >- m_sendPort = port.port(); >- >- if (m_sendPort) { >- ASSERT(MACH_PORT_VALID(m_receivePort)); >- mach_port_t previousNotificationPort = MACH_PORT_NULL; >- auto kr = mach_port_request_notification(mach_task_self(), m_receivePort, MACH_NOTIFY_NO_SENDERS, 0, MACH_PORT_NULL, MACH_MSG_TYPE_MOVE_SEND_ONCE, &previousNotificationPort); >- ASSERT(kr == KERN_SUCCESS); >- if (kr != KERN_SUCCESS) { >- // If mach_port_request_notification fails, 'previousNotificationPort' will be uninitialized. >- LOG_ERROR("mach_port_request_notification failed: (%x) %s", kr, mach_error_string(kr)); >- previousNotificationPort = MACH_PORT_NULL; >- } >- >- if (previousNotificationPort != MACH_PORT_NULL) >- deallocateSendRightSafely(previousNotificationPort); >- >- initializeSendSource(); >- dispatch_resume(m_sendSource); >- } >- >- m_isConnected = true; >- >- // Send any pending outgoing messages. >- sendOutgoingMessages(); >- >- return; >- } >- >-#if !PLATFORM(IOS_FAMILY) >- if (decoder->messageReceiverName() == "IPC" && decoder->messageName() == "SetExceptionPort") { >- if (m_isServer) { >- // Server connections aren't supposed to have their exception ports overridden. Treat this as an invalid message. >- StringReference messageReceiverNameReference = decoder->messageReceiverName(); >- String messageReceiverName(String(messageReceiverNameReference.data(), messageReceiverNameReference.size())); >- StringReference messageNameReference = decoder->messageName(); >- String messageName(String(messageNameReference.data(), messageNameReference.size())); >- >- RunLoop::main().dispatch([protectedThis = makeRef(*this), messageReceiverName = WTFMove(messageReceiverName), messageName = WTFMove(messageName)]() mutable { >- protectedThis->dispatchDidReceiveInvalidMessage(messageReceiverName.utf8(), messageName.utf8()); >- }); >- return; >- } >- MachPort exceptionPort; >- if (!decoder->decode(exceptionPort)) >- return; >- >- setMachExceptionPort(exceptionPort.port()); >- return; >- } >-#endif >- >- processIncomingMessage(WTFMove(decoder)); >-} >- >-IPC::Connection::Identifier Connection::identifier() const >-{ >- return Identifier(m_isServer ? m_receivePort : m_sendPort, m_xpcConnection); >-} >- >-Optional<audit_token_t> Connection::getAuditToken() >-{ >- if (!m_xpcConnection) >- return WTF::nullopt; >- >- audit_token_t auditToken; >- xpc_connection_get_audit_token(m_xpcConnection.get(), &auditToken); >- return WTFMove(auditToken); >-} >- >-bool Connection::kill() >-{ >- if (m_xpcConnection) { >- xpc_connection_kill(m_xpcConnection.get(), SIGKILL); >- m_wasKilled = true; >- return true; >- } >- >- return false; >-} >- >-static void AccessibilityProcessSuspendedNotification(bool suspended) >-{ >-#if PLATFORM(MAC) >- _AXUIElementNotifyProcessSuspendStatus(suspended ? AXSuspendStatusSuspended : AXSuspendStatusRunning); >-#elif PLATFORM(IOS_FAMILY) >- UIAccessibilityPostNotification(kAXPidStatusChangedNotification, @{ @"pid" : @(getpid()), @"suspended" : @(suspended) }); >-#else >- UNUSED_PARAM(suspended); >-#endif >-} >- >-void Connection::willSendSyncMessage(OptionSet<SendSyncOption> sendSyncOptions) >-{ >- if (sendSyncOptions.contains(IPC::SendSyncOption::InformPlatformProcessWillSuspend) && WebCore::AXObjectCache::accessibilityEnabled()) >- AccessibilityProcessSuspendedNotification(true); >-} >- >-void Connection::didReceiveSyncReply(OptionSet<SendSyncOption> sendSyncOptions) >-{ >- if (sendSyncOptions.contains(IPC::SendSyncOption::InformPlatformProcessWillSuspend) && WebCore::AXObjectCache::accessibilityEnabled()) >- AccessibilityProcessSuspendedNotification(false); >-} >- >-pid_t Connection::remoteProcessID() const >-{ >- if (!m_xpcConnection) >- return 0; >- >- return xpc_connection_get_pid(m_xpcConnection.get()); >-} >- >-} // namespace IPC >diff --git a/Source/WebKit/Platform/IPC/mac/ImportanceAssertion.h b/Source/WebKit/Platform/IPC/mac/ImportanceAssertion.h >deleted file mode 100644 >index 6f90b0434182bd0851ea9464830e82662b68b144..0000000000000000000000000000000000000000 >--- a/Source/WebKit/Platform/IPC/mac/ImportanceAssertion.h >+++ /dev/null >@@ -1,66 +0,0 @@ >-/* >- * Copyright (C) 2013 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >- * THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#ifndef ImportanceAssertion_h >-#define ImportanceAssertion_h >- >-#if PLATFORM(MAC) >- >-#include <mach/message.h> >- >-namespace IPC { >- >-class ImportanceAssertion { >- WTF_MAKE_FAST_ALLOCATED; >- WTF_MAKE_NONCOPYABLE(ImportanceAssertion); >- >-public: >- explicit ImportanceAssertion(mach_msg_header_t* header) >- : m_voucher(0) >- { >- if (MACH_MSGH_BITS_HAS_VOUCHER(header->msgh_bits)) { >- m_voucher = header->msgh_voucher_port; >- header->msgh_voucher_port = MACH_VOUCHER_NULL; >- header->msgh_bits &= ~(MACH_MSGH_BITS_VOUCHER_MASK | MACH_MSGH_BITS_RAISEIMP); >- } >- } >- >- ~ImportanceAssertion() >- { >- if (m_voucher) { >- kern_return_t kr = mach_voucher_deallocate(m_voucher); >- ASSERT_UNUSED(kr, !kr); >- } >- } >- >-private: >- mach_voucher_t m_voucher; >-}; >- >-} >- >-#endif // PLATFORM(MAC) >- >-#endif // ImportanceAssertion_h >diff --git a/Source/WebKit/Platform/IPC/mac/MachMessage.cpp b/Source/WebKit/Platform/IPC/mac/MachMessage.cpp >deleted file mode 100644 >index ec84c96a139af805f13f07ac7cbe024b0f53da23..0000000000000000000000000000000000000000 >--- a/Source/WebKit/Platform/IPC/mac/MachMessage.cpp >+++ /dev/null >@@ -1,74 +0,0 @@ >-/* >- * Copyright (C) 2016 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >- * THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#include "config.h" >-#include "MachMessage.h" >- >-#if PLATFORM(COCOA) >- >-#include <mach/mach.h> >- >-namespace IPC { >- >-std::unique_ptr<MachMessage> MachMessage::create(CString&& messageReceiverName, CString&& messageName, size_t size) >-{ >- void* memory = WTF::fastZeroedMalloc(sizeof(MachMessage) + size); >- return std::unique_ptr<MachMessage> { new (NotNull, memory) MachMessage { WTFMove(messageReceiverName), WTFMove(messageName), size } }; >-} >- >-MachMessage::MachMessage(CString&& messageReceiverName, CString&& messageName, size_t size) >- : m_messageReceiverName(WTFMove(messageReceiverName)) >- , m_messageName(WTFMove(messageName)) >- , m_size { size } >-{ >-} >- >-MachMessage::~MachMessage() >-{ >- if (m_shouldFreeDescriptors) >- ::mach_msg_destroy(header()); >-} >- >-size_t MachMessage::messageSize(size_t bodySize, size_t portDescriptorCount, size_t memoryDescriptorCount) >-{ >- size_t messageSize = sizeof(mach_msg_header_t) + bodySize; >- >- if (portDescriptorCount || memoryDescriptorCount) { >- messageSize += sizeof(mach_msg_body_t); >- messageSize += (portDescriptorCount * sizeof(mach_msg_port_descriptor_t)); >- messageSize += (memoryDescriptorCount * sizeof(mach_msg_ool_descriptor_t)); >- } >- >- return round_msg(messageSize); >-} >- >-void MachMessage::leakDescriptors() >-{ >- m_shouldFreeDescriptors = false; >-} >- >-} >- >-#endif // PLATFORM(COCOA) >diff --git a/Source/WebKit/Platform/IPC/mac/MachMessage.h b/Source/WebKit/Platform/IPC/mac/MachMessage.h >deleted file mode 100644 >index d0131c7f0d3efa38af4054e276d4fc286c93442c..0000000000000000000000000000000000000000 >--- a/Source/WebKit/Platform/IPC/mac/MachMessage.h >+++ /dev/null >@@ -1,64 +0,0 @@ >-/* >- * Copyright (C) 2016 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >- * THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#pragma once >- >-#if PLATFORM(COCOA) >- >-#include <mach/message.h> >-#include <memory> >-#include <wtf/text/CString.h> >- >-namespace IPC { >- >-class MachMessage { >- WTF_MAKE_FAST_ALLOCATED; >-public: >- static std::unique_ptr<MachMessage> create(CString&& messageReceiverName, CString&& messageName, size_t); >- ~MachMessage(); >- >- static size_t messageSize(size_t bodySize, size_t portDescriptorCount, size_t memoryDescriptorCount); >- >- size_t size() const { return m_size; } >- mach_msg_header_t* header() { return m_messageHeader; } >- >- void leakDescriptors(); >- >- const CString& messageReceiverName() const { return m_messageReceiverName; } >- const CString& messageName() const { return m_messageName; } >- >-private: >- MachMessage(CString&& messageReceiverName, CString&& messageName, size_t); >- >- CString m_messageReceiverName; >- CString m_messageName; >- size_t m_size; >- bool m_shouldFreeDescriptors { true }; >- mach_msg_header_t m_messageHeader[]; >-}; >- >-} >- >-#endif // PLATFORM(COCOA) >diff --git a/Source/WebKit/Platform/IPC/mac/MachPort.h b/Source/WebKit/Platform/IPC/mac/MachPort.h >deleted file mode 100644 >index 9144a052ea0cf429e807366158d4d18237241e2b..0000000000000000000000000000000000000000 >--- a/Source/WebKit/Platform/IPC/mac/MachPort.h >+++ /dev/null >@@ -1,75 +0,0 @@ >-/* >- * Copyright (C) 2010 Apple Inc. All rights reserved. >- * >- * Redistribution and use in source and binary forms, with or without >- * modification, are permitted provided that the following conditions >- * are met: >- * 1. Redistributions of source code must retain the above copyright >- * notice, this list of conditions and the following disclaimer. >- * 2. Redistributions in binary form must reproduce the above copyright >- * notice, this list of conditions and the following disclaimer in the >- * documentation and/or other materials provided with the distribution. >- * >- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' >- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, >- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS >- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR >- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF >- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS >- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN >- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) >- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF >- * THE POSSIBILITY OF SUCH DAMAGE. >- */ >- >-#ifndef MachPort_h >-#define MachPort_h >- >-#include "Attachment.h" >-#include "Decoder.h" >-#include "Encoder.h" >- >-namespace IPC { >- >-class MachPort { >-public: >- MachPort() >- : m_port(MACH_PORT_NULL) >- , m_disposition(0) >- { >- } >- >- MachPort(mach_port_name_t port, mach_msg_type_name_t disposition) >- : m_port(port) >- , m_disposition(disposition) >- { >- } >- >- void encode(Encoder& encoder) const >- { >- encoder << Attachment(m_port, m_disposition); >- } >- >- static bool decode(Decoder& decoder, MachPort& p) >- { >- Attachment attachment; >- if (!decoder.decode(attachment)) >- return false; >- >- p.m_port = attachment.port(); >- p.m_disposition = attachment.disposition(); >- return true; >- } >- >- mach_port_name_t port() const { return m_port; } >- mach_msg_type_name_t disposition() const { return m_disposition; } >- >-private: >- mach_port_name_t m_port; >- mach_msg_type_name_t m_disposition; >-}; >- >-} // namespace IPC >- >-#endif // MachPort_h >diff --git a/Source/WebKit/PlatformMac.cmake b/Source/WebKit/PlatformMac.cmake >index 44084a62ea2177275f603b313f0f14444fdc41e7..d16c1212f7f63872697920eae87ebd41b45c9970 100644 >--- a/Source/WebKit/PlatformMac.cmake >+++ b/Source/WebKit/PlatformMac.cmake >@@ -42,8 +42,8 @@ list(APPEND WebKit_SOURCES > NetworkProcess/mac/NetworkProcessMac.mm > NetworkProcess/mac/RemoteNetworkingContext.mm > >- Platform/IPC/mac/ConnectionMac.mm >- Platform/IPC/mac/MachMessage.cpp >+ Platform/IPC/cocoa/ConnectionCocoa.mm >+ Platform/IPC/cocoa/MachMessage.cpp > > Platform/cf/ModuleCF.cpp > >diff --git a/Source/WebKit/SourcesCocoa.txt b/Source/WebKit/SourcesCocoa.txt >index ed4b0f0fb6c20802650882cbb841c75f9f9e9fe0..ced1b9370ef55c31760173408e55937f7a018e82 100644 >--- a/Source/WebKit/SourcesCocoa.txt >+++ b/Source/WebKit/SourcesCocoa.txt >@@ -74,8 +74,8 @@ Platform/foundation/LoggingFoundation.mm > Platform/ios/AccessibilityIOS.mm > Platform/ios/PaymentAuthorizationController.mm > >-Platform/IPC/mac/ConnectionMac.mm >-Platform/IPC/mac/MachMessage.cpp >+Platform/IPC/cocoa/ConnectionCoca.mm >+Platform/IPC/cocoa/MachMessage.cpp > > Platform/mac/LayerHostingContext.mm > Platform/mac/MachUtilities.cpp >diff --git a/Source/WebKit/WebKit.xcodeproj/project.pbxproj b/Source/WebKit/WebKit.xcodeproj/project.pbxproj >index 37879b54ac6301c485e20d4de4eeff58f3a609a4..32c6820f80ca9533e8dab7b1f767cb7ef38fac17 100644 >--- a/Source/WebKit/WebKit.xcodeproj/project.pbxproj >+++ b/Source/WebKit/WebKit.xcodeproj/project.pbxproj >@@ -2063,7 +2063,7 @@ > 1A2D956D12848564001EB962 /* AuxiliaryProcess.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AuxiliaryProcess.h; sourceTree = "<group>"; }; > 1A2D956E12848564001EB962 /* AuxiliaryProcess.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AuxiliaryProcess.cpp; sourceTree = "<group>"; }; > 1A30066C1110F4F70031937C /* ResponsivenessTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResponsivenessTimer.h; sourceTree = "<group>"; }; >- 1A30EAC5115D7DA30053E937 /* ConnectionMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ConnectionMac.mm; sourceTree = "<group>"; }; >+ 1A30EAC5115D7DA30053E937 /* ConnectionCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ConnectionCocoa.mm; sourceTree = "<group>"; }; > 1A334DEA16DE8B68006A8E38 /* StorageAreaMap.messages.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = StorageAreaMap.messages.in; sourceTree = "<group>"; }; > 1A334DEB16DE8F88006A8E38 /* StorageAreaMapMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StorageAreaMapMessageReceiver.cpp; path = DerivedSources/WebKit2/StorageAreaMapMessageReceiver.cpp; sourceTree = BUILT_PRODUCTS_DIR; }; > 1A334DEC16DE8F88006A8E38 /* StorageAreaMapMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StorageAreaMapMessages.h; path = DerivedSources/WebKit2/StorageAreaMapMessages.h; sourceTree = BUILT_PRODUCTS_DIR; }; >@@ -5490,7 +5490,7 @@ > 1AE00D6818327C1200087DD7 /* IPC */ = { > isa = PBXGroup; > children = ( >- BCC56F751159955E001CCAF9 /* mac */, >+ BCC56F751159955E001CCAF9 /* cocoa */, > 1AEFD27811D16C81008219D3 /* ArgumentCoder.h */, > 1A3D610413A7F03A00F95D4E /* ArgumentCoders.cpp */, > 1AEFD2F611D1807B008219D3 /* ArgumentCoders.h */, >@@ -8332,16 +8332,16 @@ > path = WebContentService; > sourceTree = "<group>"; > }; >- BCC56F751159955E001CCAF9 /* mac */ = { >+ BCC56F751159955E001CCAF9 /* cocoa */ = { > isa = PBXGroup; > children = ( >- 1A30EAC5115D7DA30053E937 /* ConnectionMac.mm */, >+ 1A30EAC5115D7DA30053E937 /* ConnectionCocoa.mm */, > 1A1EC69D1872092100B951F0 /* ImportanceAssertion.h */, > 1A6D86BF1DF75265007745E8 /* MachMessage.cpp */, > 1A6D86C01DF75265007745E8 /* MachMessage.h */, > BCC56F771159957D001CCAF9 /* MachPort.h */, > ); >- path = mac; >+ path = cocoa; > sourceTree = "<group>"; > }; > BCCF085C113F3B7500C650C5 /* mac */ = {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 197661
:
369289
|
369291
|
369293