Title: [197457] trunk/Source/_javascript_Core
Revision
197457
Author
[email protected]
Date
2016-03-02 11:17:18 -0800 (Wed, 02 Mar 2016)

Log Message

SIGSEGV in Proxy [[Get]] and [[Set]] recursion
https://bugs.webkit.org/show_bug.cgi?id=154854

Reviewed by Yusuke Suzuki.

We need to be aware of the possibility that the VM
may recurse and that we can stack overflow.

* runtime/ProxyObject.cpp:
(JSC::performProxyGet):
(JSC::ProxyObject::performPut):
* tests/stress/proxy-get-and-set-recursion-stack-overflow.js: Added.
(assert):
(testStackOverflowGet):
(testStackOverflowIndexedGet):
(testStackOverflowSet):
(testStackOverflowIndexedSet):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (197456 => 197457)


--- trunk/Source/_javascript_Core/ChangeLog	2016-03-02 18:54:03 UTC (rev 197456)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-03-02 19:17:18 UTC (rev 197457)
@@ -1,3 +1,23 @@
+2016-03-02  Saam barati  <[email protected]>
+
+        SIGSEGV in Proxy [[Get]] and [[Set]] recursion
+        https://bugs.webkit.org/show_bug.cgi?id=154854
+
+        Reviewed by Yusuke Suzuki.
+
+        We need to be aware of the possibility that the VM
+        may recurse and that we can stack overflow.
+
+        * runtime/ProxyObject.cpp:
+        (JSC::performProxyGet):
+        (JSC::ProxyObject::performPut):
+        * tests/stress/proxy-get-and-set-recursion-stack-overflow.js: Added.
+        (assert):
+        (testStackOverflowGet):
+        (testStackOverflowIndexedGet):
+        (testStackOverflowSet):
+        (testStackOverflowIndexedSet):
+
 2016-03-02  Benjamin Poulain  <[email protected]>
 
         [JSC] Use a Move without REX byte when possible

Modified: trunk/Source/_javascript_Core/runtime/ProxyObject.cpp (197456 => 197457)


--- trunk/Source/_javascript_Core/runtime/ProxyObject.cpp	2016-03-02 18:54:03 UTC (rev 197456)
+++ trunk/Source/_javascript_Core/runtime/ProxyObject.cpp	2016-03-02 19:17:18 UTC (rev 197457)
@@ -80,6 +80,11 @@
 static EncodedJSValue performProxyGet(ExecState* exec, EncodedJSValue thisValue, PropertyName propertyName)
 {
     VM& vm = exec->vm();
+    if (!vm.isSafeToRecurse()) {
+        throwStackOverflowError(exec);
+        return JSValue::encode(JSValue());
+    }
+
     JSObject* thisObject = jsCast<JSObject*>(JSValue::decode(thisValue)); // This might be a value where somewhere in __proto__ chain lives a ProxyObject.
     JSObject* proxyObjectAsObject = thisObject;
     // FIXME: make it so that custom getters take both the |this| value and the slotBase (property holder).
@@ -345,6 +350,10 @@
 void ProxyObject::performPut(ExecState* exec, JSValue putValue, JSValue thisValue, PropertyName propertyName, PerformDefaultPutFunction performDefaultPut)
 {
     VM& vm = exec->vm();
+    if (!vm.isSafeToRecurse()) {
+        throwStackOverflowError(exec);
+        return;
+    }
 
     if (vm.propertyNames->isPrivateName(Identifier::fromUid(&vm, propertyName.uid())))
         return performDefaultPut();

Added: trunk/Source/_javascript_Core/tests/stress/proxy-get-and-set-recursion-stack-overflow.js (0 => 197457)


--- trunk/Source/_javascript_Core/tests/stress/proxy-get-and-set-recursion-stack-overflow.js	                        (rev 0)
+++ trunk/Source/_javascript_Core/tests/stress/proxy-get-and-set-recursion-stack-overflow.js	2016-03-02 19:17:18 UTC (rev 197457)
@@ -0,0 +1,67 @@
+function assert(b) {
+    if (!b)
+        throw new Error('bad assertion');
+}
+
+function testStackOverflowGet() {
+    let threw = false;
+    try {
+        let o = {};
+        let p = new Proxy(o, {});
+        Object.setPrototypeOf(o, p);
+        p.anyField;
+    } catch(e) {
+        threw = true;
+        assert(e.toString() === "RangeError: Maximum call stack size exceeded.");
+    }
+    assert(threw);
+}
+
+function testStackOverflowIndexedGet(i) {
+    let threw = false;
+    try {
+        let o = {};
+        let p = new Proxy(o, {});
+        Object.setPrototypeOf(o, p);
+        p[i];
+    } catch(e) {
+        threw = true;
+        assert(e.toString() === "RangeError: Maximum call stack size exceeded.");
+    }
+    assert(threw);
+}
+
+function testStackOverflowSet() {
+    let threw = false;
+    try {
+        let o = {};
+        let p = new Proxy(o, {});
+        Object.setPrototypeOf(o, p);
+        p.anyField = 50;
+    } catch(e) {
+        threw = true;
+        assert(e.toString() === "RangeError: Maximum call stack size exceeded.");
+    }
+    assert(threw);
+}
+
+function testStackOverflowIndexedSet(i) {
+    let threw = false;
+    try {
+        let o = {};
+        let p = new Proxy(o, {});
+        Object.setPrototypeOf(o, p);
+        p[i] = 50;
+    } catch(e) {
+        threw = true;
+        assert(e.toString() === "RangeError: Maximum call stack size exceeded.");
+    }
+    assert(threw);
+}
+
+for (let i = 0; i < 250; i++) {
+    testStackOverflowGet();
+    testStackOverflowIndexedGet(i);
+    testStackOverflowSet();
+    testStackOverflowIndexedSet(i);
+}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to