Skip to content

Commit

Permalink
Cherry-pick 259548.825@safari-7615-branch (9b3d228). rdar://110459666
Browse files Browse the repository at this point in the history
    jsc_fuz/wktr: null ptr deref in WebCore::IDBRequest::dispatchEvent(WebCore::Event&)
    rdar://110459666

    Reviewed by Brady Eidson.

    Make sure untrusted event does not change the internal state of IDBRequest. Also, move the assert that request must have
    pending activity when event is being dispatched to a later point, because IDBRequest::dispatchEvent might be invoked
    from JavaScript code (i.e. request does not actually have pending activity).

    Test: storage/indexeddb/modern/request-dispatch-untrusted-event.html
          storage/indexeddb/modern/request-dispatch-untrusted-event-private.html

    * LayoutTests/storage/indexeddb/modern/request-dispatch-untrusted-event-expected.txt: Added.
    * LayoutTests/storage/indexeddb/modern/request-dispatch-untrusted-event-private-expected.txt: Added.
    * LayoutTests/storage/indexeddb/modern/request-dispatch-untrusted-event-private.html: Added.
    * LayoutTests/storage/indexeddb/modern/request-dispatch-untrusted-event.html: Added.
    * LayoutTests/storage/indexeddb/modern/resources/request-dispatch-untrusted-event.js: Added.
    (loadImage):
    (openDatabase):
    * Source/WebCore/Modules/indexeddb/IDBRequest.cpp:
    (WebCore::IDBRequest::dispatchEvent):

    Canonical link: https://commits.webkit.org/259548.825@safari-7615-branch
  • Loading branch information
szewai authored and mcatanzaro committed Jul 28, 2023
1 parent 77073e6 commit bf79ad4
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
This test verifies dispatching untrusted event should not cause crash.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


image = new Image();
openRequest = indexedDB.open(dbname);
PASS successfullyParsed is true

TEST COMPLETE

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
This test verifies dispatching untrusted event should not cause crash.

On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".


image = new Image();
openRequest = indexedDB.open(dbname);
PASS successfullyParsed is true

TEST COMPLETE

Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!-- webkit-test-runner [ useEphemeralSession=true ] -->
<html>
<head>
<script src="../../../resources/js-test.js"></script>
<script src="../resources/shared.js"></script>
</head>
<body>
<script src="resources/request-dispatch-untrusted-event.js"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<html>
<head>
<script src="../../../resources/js-test.js"></script>
<script src="../resources/shared.js"></script>
</head>
<body>
<script src="resources/request-dispatch-untrusted-event.js"></script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
description("This test verifies dispatching untrusted event should not cause crash.");

setDBNameFromPath();

function loadImage()
{
evalAndLog("image = new Image();");
image.onerror = (error) => {
imageError = error;
openDatabase();
};
// Generate an error event.
image.src = 'data:';
}

function openDatabase()
{
evalAndLog("openRequest = indexedDB.open(dbname);");
openRequest.onupgradeneeded = () => { openRequest.dispatchEvent(imageError); };
// Ensure there is no crash after error event is dispatched.
openRequest.onerror = () => { setTimeout(finishJSTest, 0); };
}

loadImage();
11 changes: 7 additions & 4 deletions Source/WebCore/Modules/indexeddb/IDBRequest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,10 +296,15 @@ void IDBRequest::dispatchEvent(Event& event)
LOG(IndexedDB, "IDBRequest::dispatchEvent - %s (%p)", event.type().string().utf8().data(), this);

ASSERT(canCurrentThreadAccessThreadLocalData(originThread()));
ASSERT(m_hasPendingActivity);
ASSERT(!isContextStopped());

Ref protectedThis { *this };
if (!event.isTrusted()) {
EventDispatcher::dispatchEvent({ this }, event);
return;
}

ASSERT(m_hasPendingActivity);
m_eventBeingDispatched = &event;

if (event.type() != eventNames().blockedEvent)
Expand All @@ -312,9 +317,7 @@ void IDBRequest::dispatchEvent(Event& event)
else if (m_transaction && !m_transaction->didDispatchAbortOrCommit())
targets = { this, m_transaction.get(), &m_transaction->database() };

if (event.isTrusted())
m_hasPendingActivity = false;

m_hasPendingActivity = false;
{
TransactionActivator activator(m_transaction.get());
EventDispatcher::dispatchEvent(targets, event);
Expand Down

0 comments on commit bf79ad4

Please sign in to comment.