Changeset 247322 in webkit


Ignore:
Timestamp:
Jul 10, 2019 1:10:49 PM (5 years ago)
Author:
Chris Dumez
Message:

Crash under IPC::Connection::waitForMessage()
https://bugs.webkit.org/show_bug.cgi?id=199680
<rdar://problem/52500561>

Reviewed by Tim Horton.

IPC::Connection::waitForMessage() is crashing due to a null defererence of
m_waitingForMessage. Since m_waitingForMessage is only ever set to null in
waitForMessage(), this seems to imply we've re-entered waitForMessage().
This is in theory possible since the loop inside waitForMessage() calls
SyncMessageState::singleton().dispatchMessages() on every iteration to
process incoming synchronous IPC messages. In theory, one of these sync
IPC messages could run code which ends up calling waitForAndDispatchImmediately()
(and thus waitForMessage()).

We had a debug assertion to try and catch re-entrancy with a comment stating
"We don't support having multiple clients waiting for messages." but we
would not see those in release and we would crash with a null dereference
instead.

To address the crashes in release, return early in case of re-entrancy
(we would still hit an assertion in debug).

  • Platform/IPC/Connection.cpp:

(IPC::Connection::Connection):
(IPC::Connection::waitForMessage):

  • Platform/IPC/Connection.h:
Location:
trunk/Source/WebKit
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r247321 r247322  
     12019-07-10  Chris Dumez  <cdumez@apple.com>
     2
     3        Crash under IPC::Connection::waitForMessage()
     4        https://bugs.webkit.org/show_bug.cgi?id=199680
     5        <rdar://problem/52500561>
     6
     7        Reviewed by Tim Horton.
     8
     9        IPC::Connection::waitForMessage() is crashing due to a null defererence of
     10        m_waitingForMessage. Since m_waitingForMessage is only ever set to null in
     11        waitForMessage(), this seems to imply we've re-entered waitForMessage().
     12        This is in theory possible since the loop inside waitForMessage() calls
     13        SyncMessageState::singleton().dispatchMessages() on every iteration to
     14        process incoming synchronous IPC messages. In theory, one of these sync
     15        IPC messages could run code which ends up calling waitForAndDispatchImmediately()
     16        (and thus waitForMessage()).
     17
     18        We had a debug assertion to try and catch re-entrancy with a comment stating
     19        "We don't support having multiple clients waiting for messages." but we
     20        would not see those in release and we would crash with a null dereference
     21        instead.
     22
     23        To address the crashes in release, return early in case of re-entrancy
     24        (we would still hit an assertion in debug).
     25
     26        * Platform/IPC/Connection.cpp:
     27        (IPC::Connection::Connection):
     28        (IPC::Connection::waitForMessage):
     29        * Platform/IPC/Connection.h:
     30
    1312019-07-10  Tim Horton  <timothy_horton@apple.com>
    232
  • trunk/Source/WebKit/Platform/IPC/Connection.cpp

    r247020 r247322  
    261261    , m_inDispatchMessageMarkedDispatchWhenWaitingForSyncReplyCount(0)
    262262    , m_didReceiveInvalidMessage(false)
    263     , m_waitingForMessage(nullptr)
    264263    , m_shouldWaitForSyncReplies(true)
    265264{
     
    469468{
    470469    ASSERT(RunLoop::isMain());
     470    auto protectedThis = makeRef(*this);
    471471
    472472    timeout = timeoutRespectingIgnoreTimeoutsForTesting(timeout);
     
    495495    // Don't even start waiting if we have InterruptWaitingIfSyncMessageArrives and there's a sync message already in the queue.
    496496    if (hasIncomingSynchronousMessage && waitForOptions.contains(WaitForOption::InterruptWaitingIfSyncMessageArrives)) {
    497         m_waitingForMessage = nullptr;
    498         return nullptr;
    499     }
    500 
    501     WaitForMessageState waitingForMessage(messageReceiverName, messageName, destinationID, waitForOptions);
    502 
    503     {
     497#if !ASSERT_DISABLED
    504498        std::lock_guard<Lock> lock(m_waitForMessageMutex);
    505 
    506499        // We don't support having multiple clients waiting for messages.
    507500        ASSERT(!m_waitingForMessage);
     501#endif
     502        return nullptr;
     503    }
     504
     505    WaitForMessageState waitingForMessage(messageReceiverName, messageName, destinationID, waitForOptions);
     506
     507    {
     508        std::lock_guard<Lock> lock(m_waitForMessageMutex);
     509
     510        // We don't support having multiple clients waiting for messages.
     511        ASSERT(!m_waitingForMessage);
     512        if (m_waitingForMessage)
     513            return nullptr;
    508514
    509515        m_waitingForMessage = &waitingForMessage;
  • trunk/Source/WebKit/Platform/IPC/Connection.h

    r247078 r247322  
    354354
    355355    struct WaitForMessageState;
    356     WaitForMessageState* m_waitingForMessage;
     356    WaitForMessageState* m_waitingForMessage { nullptr };
    357357
    358358    class SyncMessageState;
Note: See TracChangeset for help on using the changeset viewer.