Title: [173178] trunk
Revision
173178
Author
msab...@apple.com
Date
2014-09-02 09:52:35 -0700 (Tue, 02 Sep 2014)

Log Message

Out of bounds write in vmEntryToJavaScript / JSC::JITCode::execute
https://bugs.webkit.org/show_bug.cgi?id=136305

Reviewed by Filip Pizlo.

Source/_javascript_Core:

While preparing the callee's CallFrame, ProtoCallFrame fixes any arity mismatch
and then JITCode::execute() calls the normal entrypoint.  This is incompatible
with the expectation of FTL generated functions.  Changed ProtoCallFrame to not 
perform the arity fix, but just flag an arity mismatch.  now JITCode::execute()
uses that arity mismatch condition to select the normal or arity check
entrypoint.  The entrypoint selection is only done for functions, programs
and eval always have one parameter.

* interpreter/ProtoCallFrame.cpp:
(JSC::ProtoCallFrame::init): Changed to flag arity mismatch instead of fixing it.
* interpreter/ProtoCallFrame.h:
(JSC::ProtoCallFrame::needArityCheck): New boolean to signify what entrypoint
should be called.
* jit/JITCode.cpp:
(JSC::JITCode::execute): Select normal or arity check entrypoint as appropriate.

LayoutTests:

* js/arity-mismatch-at-vmentry-expected.txt: Added.
* js/arity-mismatch-at-vmentry.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (173177 => 173178)


--- trunk/LayoutTests/ChangeLog	2014-09-02 16:47:11 UTC (rev 173177)
+++ trunk/LayoutTests/ChangeLog	2014-09-02 16:52:35 UTC (rev 173178)
@@ -1,3 +1,13 @@
+2014-09-02  Michael Saboff  <msab...@apple.com>
+
+        Out of bounds write in vmEntryToJavaScript / JSC::JITCode::execute
+        https://bugs.webkit.org/show_bug.cgi?id=136305
+
+        Reviewed by Filip Pizlo.
+
+        * js/arity-mismatch-at-vmentry-expected.txt: Added.
+        * js/arity-mismatch-at-vmentry.html: Added.
+
 2014-09-02  Youenn Fablet  <youenn.fab...@crf.canon.fr>
 
         CachedResourceLoader should check redirections to reuse or not cached resources

Added: trunk/LayoutTests/js/arity-mismatch-at-vmentry-expected.txt (0 => 173178)


--- trunk/LayoutTests/js/arity-mismatch-at-vmentry-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/arity-mismatch-at-vmentry-expected.txt	2014-09-02 16:52:35 UTC (rev 173178)
@@ -0,0 +1,9 @@
+This tests that vm entry to a JS function with arity mismatch doesn't crash (bug 136305).
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/arity-mismatch-at-vmentry.html (0 => 173178)


--- trunk/LayoutTests/js/arity-mismatch-at-vmentry.html	                        (rev 0)
+++ trunk/LayoutTests/js/arity-mismatch-at-vmentry.html	2014-09-02 16:52:35 UTC (rev 173178)
@@ -0,0 +1,42 @@
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<span id="span">
+<p id="description"></p>
+<div id="console"></div>
+
+<script>
+    description("This tests that vm entry to a JS function with arity mismatch doesn't crash (bug 136305).");
+
+    if (window.testRunner)
+        testRunner.waitUntilDone();
+
+    window.jsTestIsAsync = true;
+
+    function marsaglia(m_z, m_w, n) {
+        var result;
+        for (var i = 0; i < n; ++i) {
+        }
+    }
+
+    var result = 0;
+    for (var i = 0; i < 100; ++i)
+        result += marsaglia(i, i + 1, 1000000);
+
+    document.getElementById("span").addEventListener("readystatechange", marsaglia);
+
+    var dispatch_fn = function() {
+        evt = document.createEvent("Event");
+        evt.initEvent("readystatechange");
+        document.getElementById("span").dispatchEvent(evt);
+    }
+
+    window.setInterval(dispatch_fn, 0);
+    window.setTimeout('finishJSTest()', 1);
+</script>
+
+<script src=""
+</body>
+</html>

Modified: trunk/Source/_javascript_Core/ChangeLog (173177 => 173178)


--- trunk/Source/_javascript_Core/ChangeLog	2014-09-02 16:47:11 UTC (rev 173177)
+++ trunk/Source/_javascript_Core/ChangeLog	2014-09-02 16:52:35 UTC (rev 173178)
@@ -1,3 +1,26 @@
+2014-09-02  Michael Saboff  <msab...@apple.com>
+
+        Out of bounds write in vmEntryToJavaScript / JSC::JITCode::execute
+        https://bugs.webkit.org/show_bug.cgi?id=136305
+
+        Reviewed by Filip Pizlo.
+
+        While preparing the callee's CallFrame, ProtoCallFrame fixes any arity mismatch
+        and then JITCode::execute() calls the normal entrypoint.  This is incompatible
+        with the expectation of FTL generated functions.  Changed ProtoCallFrame to not 
+        perform the arity fix, but just flag an arity mismatch.  now JITCode::execute()
+        uses that arity mismatch condition to select the normal or arity check
+        entrypoint.  The entrypoint selection is only done for functions, programs
+        and eval always have one parameter.
+
+        * interpreter/ProtoCallFrame.cpp:
+        (JSC::ProtoCallFrame::init): Changed to flag arity mismatch instead of fixing it.
+        * interpreter/ProtoCallFrame.h:
+        (JSC::ProtoCallFrame::needArityCheck): New boolean to signify what entrypoint
+        should be called.
+        * jit/JITCode.cpp:
+        (JSC::JITCode::execute): Select normal or arity check entrypoint as appropriate.
+
 2014-09-02  pe...@outlook.com  <pe...@outlook.com>
 
         [WinCairo] testapi.exe is not built.

Modified: trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.cpp (173177 => 173178)


--- trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.cpp	2014-09-02 16:47:11 UTC (rev 173177)
+++ trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.cpp	2014-09-02 16:52:35 UTC (rev 173178)
@@ -39,14 +39,13 @@
     this->setScope(scope);
     this->setCallee(callee);
     this->setArgumentCountIncludingThis(argCountIncludingThis);
-    size_t paddedArgsCount = argCountIncludingThis;
-    if (codeBlock) {
-        size_t numParameters = codeBlock->numParameters();
-        if (paddedArgsCount < numParameters)
-            paddedArgsCount = numParameters;
-    }
-    // Round up paddedArgsCount to keep the stack frame size aligned.
-    paddedArgsCount = roundArgumentCountToAlignFrame(paddedArgsCount);
+    if (codeBlock && argCountIncludingThis < codeBlock->numParameters())
+        this->arityMissMatch = true;
+    else
+        this->arityMissMatch = false;
+
+    // Round up argCountIncludingThis to keep the stack frame size aligned.
+    size_t paddedArgsCount = roundArgumentCountToAlignFrame(argCountIncludingThis);
     this->setPaddedArgCount(paddedArgsCount);
     this->clearCurrentVPC();
     this->setThisValue(thisValue);

Modified: trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.h (173177 => 173178)


--- trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.h	2014-09-02 16:47:11 UTC (rev 173177)
+++ trunk/Source/_javascript_Core/interpreter/ProtoCallFrame.h	2014-09-02 16:52:35 UTC (rev 173178)
@@ -37,6 +37,7 @@
     Register argCountAndCodeOriginValue;
     Register thisArg;
     uint32_t paddedArgCount;
+    bool arityMissMatch;
     JSValue *args;
 
     void init(CodeBlock*, JSScope*, JSObject*, JSValue, int, JSValue* otherArgs = 0);
@@ -60,6 +61,8 @@
     JSValue thisValue() const { return thisArg.Register::jsValue(); }
     void setThisValue(JSValue value) { thisArg = value; }
 
+    bool needArityCheck() { return arityMissMatch; }
+
     JSValue argument(size_t argumentIndex)
     {
         ASSERT(static_cast<int>(argumentIndex) < argumentCount());

Modified: trunk/Source/_javascript_Core/jit/JITCode.cpp (173177 => 173178)


--- trunk/Source/_javascript_Core/jit/JITCode.cpp	2014-09-02 16:47:11 UTC (rev 173177)
+++ trunk/Source/_javascript_Core/jit/JITCode.cpp	2014-09-02 16:52:35 UTC (rev 173178)
@@ -28,6 +28,7 @@
 
 #include "LLIntThunks.h"
 #include "JSCInlines.h"
+#include "ProtoCallFrame.h"
 #include "RegisterPreservationWrapperGenerator.h"
 #include <wtf/PrintStream.h>
 
@@ -44,7 +45,15 @@
 
 JSValue JITCode::execute(VM* vm, ProtoCallFrame* protoCallFrame)
 {
-    JSValue result = JSValue::decode(vmEntryToJavaScript(executableAddress(), vm, protoCallFrame));
+    void* entryAddress;
+    JSFunction* function = jsCast<JSFunction*>(protoCallFrame->callee());
+
+    if (!function || !protoCallFrame->needArityCheck()) {
+        ASSERT(!protoCallFrame->needArityCheck());
+        entryAddress = executableAddress();
+    } else
+        entryAddress = addressForCall(*vm, function->executable(), MustCheckArity, RegisterPreservationNotRequired).executableAddress();
+    JSValue result = JSValue::decode(vmEntryToJavaScript(entryAddress, vm, protoCallFrame));
     return vm->exception() ? jsNull() : result;
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to