Stack overflow crash in JSC::JSObject::hasInstance.
authormark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 9 Mar 2019 01:10:33 +0000 (01:10 +0000)
committermark.lam@apple.com <mark.lam@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 9 Mar 2019 01:10:33 +0000 (01:10 +0000)
https://bugs.webkit.org/show_bug.cgi?id=195458
<rdar://problem/48710195>

Reviewed by Yusuke Suzuki.

JSTests:

* stress/stack-overflow-in-custom-hasInstance.js: Added.

Source/JavaScriptCore:

* runtime/JSObject.cpp:
(JSC::JSObject::hasInstance):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@242667 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JSTests/ChangeLog
JSTests/stress/stack-overflow-in-custom-hasInstance.js [new file with mode: 0644]
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/JSObject.cpp

index e958f86..52b6a7b 100644 (file)
@@ -1,3 +1,13 @@
+2019-03-08  Mark Lam  <mark.lam@apple.com>
+
+        Stack overflow crash in JSC::JSObject::hasInstance.
+        https://bugs.webkit.org/show_bug.cgi?id=195458
+        <rdar://problem/48710195>
+
+        Reviewed by Yusuke Suzuki.
+
+        * stress/stack-overflow-in-custom-hasInstance.js: Added.
+
 2019-03-08  Tadeu Zagallo  <tzagallo@apple.com>
 
         op_check_tdz does not def its argument
diff --git a/JSTests/stress/stack-overflow-in-custom-hasInstance.js b/JSTests/stress/stack-overflow-in-custom-hasInstance.js
new file mode 100644 (file)
index 0000000..c1e2eb0
--- /dev/null
@@ -0,0 +1,28 @@
+//@ requireOptions("--maxPerThreadStackUsage=147456", "--exceptionStackTraceLimit=1", "--defaultErrorStackTraceLimit=1")
+
+function f() {}
+
+var fn = f;
+for (var i = 0; i < 100000; ++i) {
+    fn = fn.bind();
+
+    // Ensure we don't fallback to @@hasInstance from %FunctionPrototype%.
+    Object.defineProperty(fn, Symbol.hasInstance, {
+        value: undefined, writable: true, enumerable: true, writable: true
+    });
+
+    // Prevent generating overlong names of the form "bound bound bound [...] f".
+    Object.defineProperty(fn, "name", {
+        value: "", writable: true, enumerable: true, writable: true
+    });
+}
+
+var exception;
+try {
+    ({}) instanceof fn;
+} catch (e) {
+    exception = e;
+}
+
+if (exception != "RangeError: Maximum call stack size exceeded.")
+    throw "FAILED";
index 705fbeb..1bc8bde 100644 (file)
@@ -1,3 +1,14 @@
+2019-03-08  Mark Lam  <mark.lam@apple.com>
+
+        Stack overflow crash in JSC::JSObject::hasInstance.
+        https://bugs.webkit.org/show_bug.cgi?id=195458
+        <rdar://problem/48710195>
+
+        Reviewed by Yusuke Suzuki.
+
+        * runtime/JSObject.cpp:
+        (JSC::JSObject::hasInstance):
+
 2019-03-08  Robin Morisset  <rmorisset@apple.com>
 
         IntegerCheckCombiningPhase::Range can be shrunk by 8 bytes
index b5f768f..cd8f535 100644 (file)
@@ -46,6 +46,7 @@
 #include "ProxyObject.h"
 #include "SlotVisitorInlines.h"
 #include "TypeError.h"
+#include "VMInlines.h"
 #include <math.h>
 #include <wtf/Assertions.h>
 
@@ -2245,8 +2246,13 @@ bool JSObject::hasInstance(ExecState* exec, JSValue value, JSValue hasInstanceVa
         RETURN_IF_EXCEPTION(scope, false);
         RELEASE_AND_RETURN(scope, defaultHasInstance(exec, value, prototype));
     }
-    if (info.implementsHasInstance())
+    if (info.implementsHasInstance()) {
+        if (UNLIKELY(!vm.isSafeToRecurseSoft())) {
+            throwStackOverflowError(exec, scope);
+            return false;
+        }
         RELEASE_AND_RETURN(scope, methodTable(vm)->customHasInstance(this, exec, value));
+    }
 
     throwException(exec, scope, createInvalidInstanceofParameterErrorNotFunction(exec, this));
     return false;