- 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;
}