Changeset 211535 in webkit


Ignore:
Timestamp:
Feb 1, 2017 2:52:02 PM (7 years ago)
Author:
andersca@apple.com
Message:

IPC::Connection receive ports should be guarded
https://bugs.webkit.org/show_bug.cgi?id=167704

Reviewed by Tim Horton.

Guarding receive rights will make sure that they won't be closed accidentally. They are created
with a context pointer and can only be unguarded or destructed with the same context pointer.

  • Platform/IPC/mac/ConnectionMac.mm:

(IPC::Connection::platformInvalidate):
Use mach_port_destruct and pass the connection pointer as the context.

(IPC::Connection::platformInitialize):
Guard the server port with the connection pointer as the context.

(IPC::Connection::open):
Use mach_port_construct to create the port which lets us avoid a call to mach_port_set_attributes and setMachPortQueueLength.
Make the port guarded and use the connection pointer as the context.

(IPC::createReceiveSource):
Get rid of this and just duplicate the five lines of code in two places. For the receive port we want to use mach_port_destruct
in our cancel handler.

Location:
trunk/Source/WebKit2
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r211482 r211535  
     12017-02-01  Anders Carlsson  <andersca@apple.com>
     2
     3        IPC::Connection receive ports should be guarded
     4        https://bugs.webkit.org/show_bug.cgi?id=167704
     5
     6        Reviewed by Tim Horton.
     7
     8        Guarding receive rights will make sure that they won't be closed accidentally. They are created
     9        with a context pointer and can only be unguarded or destructed with the same context pointer.
     10
     11        * Platform/IPC/mac/ConnectionMac.mm:
     12        (IPC::Connection::platformInvalidate):
     13        Use mach_port_destruct and pass the connection pointer as the context.
     14
     15        (IPC::Connection::platformInitialize):
     16        Guard the server port with the connection pointer as the context.
     17
     18        (IPC::Connection::open):
     19        Use mach_port_construct to create the port which lets us avoid a call to mach_port_set_attributes and setMachPortQueueLength.
     20        Make the port guarded and use the connection pointer as the context.
     21
     22        (IPC::createReceiveSource):
     23        Get rid of this and just duplicate the five lines of code in two places. For the receive port we want to use mach_port_destruct
     24        in our cancel handler.
     25
    1262017-02-01  Andreas Kling  <akling@apple.com>
    227
  • trunk/Source/WebKit2/Platform/IPC/mac/ConnectionMac.mm

    r211390 r211535  
    121121
    122122        if (m_receivePort) {
    123             mach_port_mod_refs(mach_task_self(), m_receivePort, MACH_PORT_RIGHT_RECEIVE, -1);
     123            mach_port_destruct(mach_task_self(), m_receivePort, 0, reinterpret_cast<mach_port_context_t>(this));
    124124            m_receivePort = MACH_PORT_NULL;
    125125        }
     
    171171        m_receivePort = identifier.port;
    172172        m_sendPort = MACH_PORT_NULL;
     173
     174        mach_port_guard(mach_task_self(), m_receivePort, reinterpret_cast<mach_port_context_t>(this), true);
    173175    } else {
    174176        m_receivePort = MACH_PORT_NULL;
     
    180182
    181183    m_xpcConnection = identifier.xpcConnection;
    182 }
    183 
    184 template<typename Function>
    185 static dispatch_source_t createReceiveSource(mach_port_t receivePort, WorkQueue& workQueue, Function&& function)
    186 {
    187     dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, receivePort, 0, workQueue.dispatchQueue());
    188     dispatch_source_set_event_handler(source, function);
    189 
    190     dispatch_source_set_cancel_handler(source, ^{
    191         mach_port_mod_refs(mach_task_self(), receivePort, MACH_PORT_RIGHT_RECEIVE, -1);
    192     });
    193 
    194     return source;
    195184}
    196185
     
    206195
    207196        // Create the receive port.
    208         mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &m_receivePort);
     197        uint32_t flags = MPO_CONTEXT_AS_GUARD | MPO_QLIMIT |  MPO_STRICT | MPO_INSERT_SEND_RIGHT;
    209198
    210199#if PLATFORM(MAC)
    211         mach_port_set_attributes(mach_task_self(), m_receivePort, MACH_PORT_DENAP_RECEIVER, (mach_port_info_t)0, 0);
    212 #endif
     200        flags |= MPO_DENAP_RECEIVER;
     201#endif
     202
     203        mach_port_options_t portOptions;
     204        portOptions.flags = flags;
     205        portOptions.mpl.mpl_qlimit = MACH_PORT_QLIMIT_LARGE;
     206        mach_port_construct(mach_task_self(), &portOptions, reinterpret_cast<mach_port_context_t>(this), &m_receivePort);
    213207
    214208        m_isConnected = true;
    215209       
    216         // Send the initialize message, which contains a send right for the server to use.
    217210        auto encoder = std::make_unique<Encoder>("IPC", "InitializeConnection", 0);
    218         encoder->encode(MachPort(m_receivePort, MACH_MSG_TYPE_MAKE_SEND));
     211        encoder->encode(MachPort(m_receivePort, MACH_MSG_TYPE_MOVE_SEND));
    219212
    220213        initializeSendSource();
     
    223216    }
    224217
    225     // Change the message queue length for the receive port.
    226     setMachPortQueueLength(m_receivePort, MACH_PORT_QLIMIT_LARGE);
    227 
    228     // Register the data available handler.
    229218    RefPtr<Connection> connection(this);
    230     m_receiveSource = createReceiveSource(m_receivePort, m_connectionQueue, [connection] {
     219    m_receiveSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, m_receivePort, 0, m_connectionQueue->dispatchQueue());
     220    dispatch_source_set_event_handler(m_receiveSource, [connection] {
    231221        connection->receiveSourceEventHandler();
    232222    });
     223    dispatch_source_set_cancel_handler(m_receiveSource, [connection, receivePort = m_receivePort] {
     224        mach_port_destruct(mach_task_self(), receivePort, 0, reinterpret_cast<mach_port_context_t>(connection.get()));
     225    });
    233226
    234227#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED <= 101000
    235228    if (m_exceptionPort) {
    236         m_exceptionPortDataAvailableSource = createReceiveSource(m_exceptionPort, m_connectionQueue, [connection] {
     229        m_exceptionPortDataAvailableSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_MACH_RECV, m_exceptionPort, 0, m_connectionQueue.dispatchQueue());
     230        dispatch_source_set_event_handler(source, [connection] {
    237231            connection->exceptionSourceEventHandler();
     232        });
     233        dispatch_source_set_cancel_handler(source, [connection, exceptionPort = connection->m_exceptionPort] {
     234            mach_port_mod_refs(mach_task_self(), exceptionPort, MACH_PORT_RIGHT_RECEIVE, -1);
    238235        });
    239236
Note: See TracChangeset for help on using the changeset viewer.