Title: [287993] trunk
Revision
287993
Author
[email protected]
Date
2022-01-13 13:53:09 -0800 (Thu, 13 Jan 2022)

Log Message

null ptr deref while trying to access DeferredPromise::promise()
https://bugs.webkit.org/show_bug.cgi?id=234447

Patch by Gabriel Nava Marino <[email protected]> on 2022-01-13
Reviewed by Darin Adler.

Source/WebCore:

The sequence of steps is as follows:
1) In Document::~Document() the parent class ScriptExecutionContext::~ScriptExecutionContext() destroys the context
   on all m_destructionObservers.
2) One of these objects is a DeferredPromise created earlier and stored in the JSCustomElementRegistry's promiseMap.
3) Destroying the context via DOMGuardedObject::contextDestroyed() nulls out m_globalObject.
4) Later, an event listener is invoked and tries to access the DeferredPromise stored in the
   JSCustomElementRegistry's promiseMap.
5) However, this DeferredPromise has a null m_globalObject and we crash after trying to access it.

We should check in DeferredPromise::promise() if isEmpty().
This is true when the DeferredPromise's context has been destroyed in DOMGuardedObject::contextDestroyed().

Tests: fast/js-promise/js-promise-from-detached-iframe.html
       fast/js-promise/js-promise-invalid-context-access.html

* bindings/js/JSDOMPromiseDeferred.cpp:
(WebCore::DeferredPromise::promise const):

LayoutTests:

* fast/js-promise/js-promise-from-detached-iframe-expected.txt: Renamed from LayoutTests/fast/js-promise-from-detached-iframe-expected.txt.
* fast/js-promise/js-promise-from-detached-iframe.html: Renamed from LayoutTests/fast/js-promise-from-detached-iframe.html.
* fast/js-promise/js-promise-invalid-context-access-expected.txt: Added.
* fast/js-promise/js-promise-invalid-context-access.html: Added.
* platform/ios/TestExpectations:
* platform/win/TestExpectations:

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (287992 => 287993)


--- trunk/LayoutTests/ChangeLog	2022-01-13 21:25:03 UTC (rev 287992)
+++ trunk/LayoutTests/ChangeLog	2022-01-13 21:53:09 UTC (rev 287993)
@@ -1,3 +1,17 @@
+2022-01-13  Gabriel Nava Marino  <[email protected]>
+
+        null ptr deref while trying to access DeferredPromise::promise()
+        https://bugs.webkit.org/show_bug.cgi?id=234447
+
+        Reviewed by Darin Adler.
+
+        * fast/js-promise/js-promise-from-detached-iframe-expected.txt: Renamed from LayoutTests/fast/js-promise-from-detached-iframe-expected.txt.
+        * fast/js-promise/js-promise-from-detached-iframe.html: Renamed from LayoutTests/fast/js-promise-from-detached-iframe.html.
+        * fast/js-promise/js-promise-invalid-context-access-expected.txt: Added.
+        * fast/js-promise/js-promise-invalid-context-access.html: Added.
+        * platform/ios/TestExpectations:
+        * platform/win/TestExpectations:
+
 2022-01-13  Said Abou-Hallawa  <[email protected]>
 
         Referenced SVG filter uses always sRGB color space for its result

Copied: trunk/LayoutTests/fast/js-promise/js-promise-from-detached-iframe-expected.txt (from rev 287992, trunk/LayoutTests/fast/js-promise-from-detached-iframe-expected.txt) (0 => 287993)


--- trunk/LayoutTests/fast/js-promise/js-promise-from-detached-iframe-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/js-promise/js-promise-from-detached-iframe-expected.txt	2022-01-13 21:53:09 UTC (rev 287993)
@@ -0,0 +1,10 @@
+Tests that the promise from detached iframes do get resolved.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Promise was resolved
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Copied: trunk/LayoutTests/fast/js-promise/js-promise-from-detached-iframe.html (from rev 287992, trunk/LayoutTests/fast/js-promise-from-detached-iframe.html) (0 => 287993)


--- trunk/LayoutTests/fast/js-promise/js-promise-from-detached-iframe.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js-promise/js-promise-from-detached-iframe.html	2022-01-13 21:53:09 UTC (rev 287993)
@@ -0,0 +1,15 @@
+<!doctype html>
+<script src=""
+<body></body>
+<script>
+description("Tests that the promise from detached iframes do get resolved.");
+jsTestIsAsync = true;
+
+frame = document.createElement('iframe');
+document.body.appendChild(frame);
+frame.contentWindow.Promise.resolve("test").then(() => {
+    testPassed("Promise was resolved");
+    finishJSTest();
+});
+frame.remove();
+</script>

Added: trunk/LayoutTests/fast/js-promise/js-promise-invalid-context-access-expected.txt (0 => 287993)


--- trunk/LayoutTests/fast/js-promise/js-promise-invalid-context-access-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/js-promise/js-promise-invalid-context-access-expected.txt	2022-01-13 21:53:09 UTC (rev 287993)
@@ -0,0 +1,2 @@
+CONSOLE MESSAGE: This test passes if it does not crash.
+

Added: trunk/LayoutTests/fast/js-promise/js-promise-invalid-context-access.html (0 => 287993)


--- trunk/LayoutTests/fast/js-promise/js-promise-invalid-context-access.html	                        (rev 0)
+++ trunk/LayoutTests/fast/js-promise/js-promise-invalid-context-access.html	2022-01-13 21:53:09 UTC (rev 287993)
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<script>
+function f0() {
+  var v46 = x76.contentWindow;
+  var v61 = v46.customElements;
+  v61.whenDefined("custom-b");
+}
+function f3() {
+  var v1 = document.createElement("col");
+  v1.requestPointerLock();
+  x46.toBlob(f3,"image/png",0);
+  document._onpointerlockerror_ = f0;
+  a = new Uint8Array(1024*1024*200); // gc
+}
+_onload_ = () => {
+  if (window.testRunner)
+    testRunner.dumpAsText();
+  console.log("This test passes if it does not crash.");
+}
+</script>
+<details id="x9" _ontoggle_="f3()" open="">
+<video  _onblur_="f0()" src=""
+<iframe id="x76" srcdoc="AAAAAAAA"></iframe>
+<canvas id="x46" contenteditable="true"></canvas>

Deleted: trunk/LayoutTests/fast/js-promise-from-detached-iframe-expected.txt (287992 => 287993)


--- trunk/LayoutTests/fast/js-promise-from-detached-iframe-expected.txt	2022-01-13 21:25:03 UTC (rev 287992)
+++ trunk/LayoutTests/fast/js-promise-from-detached-iframe-expected.txt	2022-01-13 21:53:09 UTC (rev 287993)
@@ -1,10 +0,0 @@
-Tests that the promise from detached iframes do get resolved.
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS Promise was resolved
-PASS successfullyParsed is true
-
-TEST COMPLETE
-

Deleted: trunk/LayoutTests/fast/js-promise-from-detached-iframe.html (287992 => 287993)


--- trunk/LayoutTests/fast/js-promise-from-detached-iframe.html	2022-01-13 21:25:03 UTC (rev 287992)
+++ trunk/LayoutTests/fast/js-promise-from-detached-iframe.html	2022-01-13 21:53:09 UTC (rev 287993)
@@ -1,15 +0,0 @@
-<!doctype html>
-<script src=""
-<body></body>
-<script>
-description("Tests that the promise from detached iframes do get resolved.");
-jsTestIsAsync = true;
-
-frame = document.createElement('iframe');
-document.body.appendChild(frame);
-frame.contentWindow.Promise.resolve("test").then(() => {
-    testPassed("Promise was resolved");
-    finishJSTest();
-});
-frame.remove();
-</script>

Modified: trunk/LayoutTests/platform/ios/TestExpectations (287992 => 287993)


--- trunk/LayoutTests/platform/ios/TestExpectations	2022-01-13 21:25:03 UTC (rev 287992)
+++ trunk/LayoutTests/platform/ios/TestExpectations	2022-01-13 21:53:09 UTC (rev 287993)
@@ -178,6 +178,7 @@
 http/tests/pointer-lock
 fast/shadow-dom/pointerlockelement-in-shadow-tree.html
 fast/shadow-dom/pointerlockelement-in-slot.html
+fast/js-promise/js-promise-invalid-context-access.html [ Skip ]
 
 # FIXME: Media tests not supported on iOS
 http/tests/media

Modified: trunk/LayoutTests/platform/win/TestExpectations (287992 => 287993)


--- trunk/LayoutTests/platform/win/TestExpectations	2022-01-13 21:25:03 UTC (rev 287992)
+++ trunk/LayoutTests/platform/win/TestExpectations	2022-01-13 21:53:09 UTC (rev 287993)
@@ -637,6 +637,7 @@
 # Pointer Lock is not implemented.
 pointer-lock/ [ Skip ]
 http/tests/pointer-lock/ [ Skip ]
+fast/js-promise/js-promise-invalid-context-access.html [ Skip ]
 
 # Datalist is unsupported on Windows
 accessibility/datalist.html [ WontFix ]

Modified: trunk/Source/WebCore/ChangeLog (287992 => 287993)


--- trunk/Source/WebCore/ChangeLog	2022-01-13 21:25:03 UTC (rev 287992)
+++ trunk/Source/WebCore/ChangeLog	2022-01-13 21:53:09 UTC (rev 287993)
@@ -1,3 +1,28 @@
+2022-01-13  Gabriel Nava Marino  <[email protected]>
+
+        null ptr deref while trying to access DeferredPromise::promise()
+        https://bugs.webkit.org/show_bug.cgi?id=234447
+
+        Reviewed by Darin Adler.
+
+        The sequence of steps is as follows:
+        1) In Document::~Document() the parent class ScriptExecutionContext::~ScriptExecutionContext() destroys the context
+           on all m_destructionObservers.
+        2) One of these objects is a DeferredPromise created earlier and stored in the JSCustomElementRegistry's promiseMap.
+        3) Destroying the context via DOMGuardedObject::contextDestroyed() nulls out m_globalObject.
+        4) Later, an event listener is invoked and tries to access the DeferredPromise stored in the
+           JSCustomElementRegistry's promiseMap.
+        5) However, this DeferredPromise has a null m_globalObject and we crash after trying to access it.
+
+        We should check in DeferredPromise::promise() if isEmpty().
+        This is true when the DeferredPromise's context has been destroyed in DOMGuardedObject::contextDestroyed().
+
+        Tests: fast/js-promise/js-promise-from-detached-iframe.html
+               fast/js-promise/js-promise-invalid-context-access.html
+
+        * bindings/js/JSDOMPromiseDeferred.cpp:
+        (WebCore::DeferredPromise::promise const):
+
 2022-01-13  Wenson Hsieh  <[email protected]>
 
         Crash in Document::updateStyleIfNeeded() when removing a node containing the drag caret

Modified: trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.cpp (287992 => 287993)


--- trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.cpp	2022-01-13 21:25:03 UTC (rev 287992)
+++ trunk/Source/WebCore/bindings/js/JSDOMPromiseDeferred.cpp	2022-01-13 21:53:09 UTC (rev 287993)
@@ -44,6 +44,9 @@
 
 JSC::JSValue DeferredPromise::promise() const
 {
+    if (isEmpty())
+        return jsUndefined();
+
     ASSERT(deferred());
     return deferred();
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to