Diff
Modified: trunk/LayoutTests/ChangeLog (218950 => 218951)
--- trunk/LayoutTests/ChangeLog 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/LayoutTests/ChangeLog 2017-06-29 18:49:18 UTC (rev 218951)
@@ -1,3 +1,30 @@
+2017-06-29 JF Bastien <[email protected]>
+
+ WebAssembly: disable some APIs under CSP
+ https://bugs.webkit.org/show_bug.cgi?id=173892
+ <rdar://problem/32914613>
+
+ Reviewed by Daniel Bates.
+
+ These tests are basically the same as eval-blocked, but with
+ WebAssembly APIs instead of eval.
+
+ Disable all of them on iOS simulator which doesn't support
+ WebAssembly (whereas iOS does).
+
+ * http/tests/security/contentSecurityPolicy/WebAssembly-allowed-expected.txt: Added.
+ * http/tests/security/contentSecurityPolicy/WebAssembly-allowed.html: Added.
+ * http/tests/security/contentSecurityPolicy/WebAssembly-blocked-expected.txt: Added.
+ * http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-about-blank-iframe-expected.txt: Added.
+ * http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-about-blank-iframe.html: Added.
+ * http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-external-script-expected.txt: Added.
+ * http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-external-script.html: Added.
+ * http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-subframe-expected.txt: Added.
+ * http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-subframe.html: Added.
+ * http/tests/security/contentSecurityPolicy/WebAssembly-blocked.html: Added.
+ * http/tests/security/contentSecurityPolicy/resources/WebAssembly-blocked-in-external-script.js: Added.
+ * platform/ios-simulator/TestExpectations:
+
2017-06-29 Antoine Quint <[email protected]>
Full stop shows to the right of the picture-in-picture localised string in Hebrew
Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-allowed-expected.txt (0 => 218951)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-allowed-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-allowed-expected.txt 2017-06-29 18:49:18 UTC (rev 218951)
@@ -0,0 +1,2 @@
+CONSOLE MESSAGE: line 13: PASS
+
Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-allowed.html (0 => 218951)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-allowed.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-allowed.html 2017-06-29 18:49:18 UTC (rev 218951)
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-inline' 'unsafe-eval'">
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+</script>
+</head>
+<body>
+<script>
+new WebAssembly.Instance(new WebAssembly.Module(Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x1, 0x00, 0x00, 0x00)));
+console.log(`PASS`);
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-expected.txt (0 => 218951)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-expected.txt 2017-06-29 18:49:18 UTC (rev 218951)
@@ -0,0 +1,13 @@
+CONSOLE MESSAGE: line 19: EvalError: Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline'".
+
+CONSOLE MESSAGE: line 20: EvalError: Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline'".
+
+CONSOLE MESSAGE: line 21: EvalError: Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline'".
+
+CONSOLE MESSAGE: line 22: EvalError: Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline'".
+
+CONSOLE MESSAGE: line 23: EvalError: Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline'".
+
+CONSOLE MESSAGE: line 24: EvalError: Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline'".
+
+
Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-about-blank-iframe-expected.txt (0 => 218951)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-about-blank-iframe-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-about-blank-iframe-expected.txt 2017-06-29 18:49:18 UTC (rev 218951)
@@ -0,0 +1,4 @@
+ALERT: /PASS/
+CONSOLE MESSAGE: line 1: EvalError: Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline'".
+
+ WebAssembly should be blocked in the iframe, but inline script should be allowed.
Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-about-blank-iframe.html (0 => 218951)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-about-blank-iframe.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-about-blank-iframe.html 2017-06-29 18:49:18 UTC (rev 218951)
@@ -0,0 +1,12 @@
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+</script>
+<meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-inline'">
+<iframe src=""
+WebAssembly should be blocked in the iframe, but inline script should be allowed.
+<script>
+window._onload_ = function() {
+ frames[0].document.write("<script>alert(/PASS/); new WebAssembly.Instance(new WebAssembly.Module(Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x1, 0x00, 0x00, 0x00)));<\/script>");
+}
+</script>
Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-external-script-expected.txt (0 => 218951)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-external-script-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-external-script-expected.txt 2017-06-29 18:49:18 UTC (rev 218951)
@@ -0,0 +1,3 @@
+CONSOLE MESSAGE: line 1: EvalError: Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".
+
+
Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-external-script.html (0 => 218951)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-external-script.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-external-script.html 2017-06-29 18:49:18 UTC (rev 218951)
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline'">
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+</script>
+<script src=""
+</head>
+</html>
Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-subframe-expected.txt (0 => 218951)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-subframe-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-subframe-expected.txt 2017-06-29 18:49:18 UTC (rev 218951)
@@ -0,0 +1,20 @@
+CONSOLE MESSAGE: line 19: EvalError: Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline'".
+
+CONSOLE MESSAGE: line 20: EvalError: Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline'".
+
+CONSOLE MESSAGE: line 21: EvalError: Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline'".
+
+CONSOLE MESSAGE: line 22: EvalError: Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline'".
+
+CONSOLE MESSAGE: line 23: EvalError: Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline'".
+
+CONSOLE MESSAGE: line 24: EvalError: Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "script-src 'unsafe-inline'".
+
+Tests that WebAssembly is blocked in a subframe that disallows WebAssembly when the parent frame allows WebAssembly.
+
+
+
+--------
+Frame: '<!--framePath //<!--frame0-->-->'
+--------
+
Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-subframe.html (0 => 218951)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-subframe.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-subframe.html 2017-06-29 18:49:18 UTC (rev 218951)
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script>
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.dumpChildFramesAsText();
+}
+</script>
+</head>
+<body>
+<p>Tests that WebAssembly is blocked in a subframe that disallows WebAssembly when the parent frame allows WebAssembly.</p>
+<iframe src=""
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked.html (0 => 218951)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked.html (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/WebAssembly-blocked.html 2017-06-29 18:49:18 UTC (rev 218951)
@@ -0,0 +1,28 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Security-Policy" content="script-src 'unsafe-inline'">
+<script>
+if (window.testRunner)
+ testRunner.dumpAsText();
+const empty = Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x1, 0x00, 0x00, 0x00);
+</script>
+</head>
+<body>
+<!-- The WebAssembly global object and some of its members aren't blocked. -->
+<script>if (typeof WebAssembly !== "object") throw new Error(`Expected WebAssembly object to be accessible under CSP`)</script>
+<script>new WebAssembly.CompileError(`This is OK`)</script>
+<script>new WebAssembly.LinkError(`This is OK`)</script>
+<script>new WebAssembly.Module(empty)</script>
+<script>if (!WebAssembly.validate(empty)) throw new Error(`Expected validation to succeed`)</script>
+<!-- The following APIs aren't accessible under CSP. -->
+<script>new WebAssembly.Memory({ initial: 1 })</script>
+<script>new WebAssembly.Memory({ initial: 1, maximum: 1 })</script>
+<script>new WebAssembly.Memory({ initial: 1, maximum: 1, shared: true })</script>
+<script>new WebAssembly.Table({ element: "anyfunc", initial: 1 })</script>
+<script>new WebAssembly.Table({ element: "anyfunc", initial: 1, maximum: 1 })</script>
+<script>new WebAssembly.Instance(new WebAssembly.Module(empty))</script>
+<!-- FIXME: add WebAssembly.compile and WebAssembly.instantiate https://bugs.webkit.org/show_bug.cgi?id=173977 -->
+<!-- FIXME: add WebAssembly.compileStreaming and WebAssembly.instantiateStreaming https://bugs.webkit.org/show_bug.cgi?id=173105 -->
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/resources/WebAssembly-blocked-in-external-script.js (0 => 218951)
--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/resources/WebAssembly-blocked-in-external-script.js (rev 0)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/resources/WebAssembly-blocked-in-external-script.js 2017-06-29 18:49:18 UTC (rev 218951)
@@ -0,0 +1 @@
+new WebAssembly.Instance(new WebAssembly.Module(Uint8Array.of(0x0, 0x61, 0x73, 0x6d, 0x1, 0x00, 0x00, 0x00)));
Modified: trunk/LayoutTests/platform/ios-simulator/TestExpectations (218950 => 218951)
--- trunk/LayoutTests/platform/ios-simulator/TestExpectations 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/LayoutTests/platform/ios-simulator/TestExpectations 2017-06-29 18:49:18 UTC (rev 218951)
@@ -132,3 +132,10 @@
# This test relies on Arial being used to draw Arabic. However, on iOS,
# we explicitly disallow this because this font is too slow.
fast/text/initial-advance-in-intermediate-run-complex.html [ ImageOnlyFailure ]
+
+# Simulator doesn't support WebAssembly.
+http/tests/security/contentSecurityPolicy/WebAssembly-allowed.html [ Failure ]
+http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-about-blank-iframe.html [ Failure ]
+http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-external-script.html [ Failure ]
+http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-subframe.html [ Failure ]
+http/tests/security/contentSecurityPolicy/WebAssembly-blocked.html [ Failure ]
Modified: trunk/Source/_javascript_Core/ChangeLog (218950 => 218951)
--- trunk/Source/_javascript_Core/ChangeLog 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/_javascript_Core/ChangeLog 2017-06-29 18:49:18 UTC (rev 218951)
@@ -1,3 +1,79 @@
+2017-06-29 JF Bastien <[email protected]>
+
+ WebAssembly: disable some APIs under CSP
+ https://bugs.webkit.org/show_bug.cgi?id=173892
+ <rdar://problem/32914613>
+
+ Reviewed by Daniel Bates.
+
+ We should disable parts of WebAssembly under Content Security
+ Policy as discussed here:
+
+ https://github.com/WebAssembly/design/issues/1092
+
+ Exactly what should be disabled isn't super clear, so we may as
+ well be conservative and disable many things if developers already
+ opted into CSP. It's easy to loosen what we disable later.
+
+ This patch disables:
+ - WebAssembly.Instance
+ - WebAssembly.instantiate
+ - WebAssembly.Memory
+ - WebAssembly.Table
+
+ And leaves:
+ - WebAssembly on the global object
+ - WebAssembly.Module
+ - WebAssembly.compile
+ - WebAssembly.CompileError
+ - WebAssembly.LinkError
+
+ Nothing because currently unimplmented:
+ - WebAssembly.compileStreaming
+ - WebAssembly.instantiateStreaming
+
+ That way it won't be possible to call WebAssembly-compiled code,
+ or create memories (which use fancy 4GiB allocations
+ sometimes). Table isn't really useful on its own, and eventually
+ we may make them shareable so without more details it seems benign
+ to disable them (and useless if we don't).
+
+ I haven't done anything with postMessage, so you can still
+ postMessage a WebAssembly.Module cross-CSP, but you can't
+ instantiate it so it's useless. Because of this I elected to leave
+ WebAssembly.Module and friends available.
+
+ I haven't added any new directives. It's still unsafe-eval. We can
+ add something else later, but it seems odd to add a WebAssembly as
+ a new capability and tell developers "you should have been using
+ this directive which we just implemented if you wanted to disable
+ WebAssembly which didn't exist when you adopted CSP". So IMO we
+ should keep unsafe-eval as it currently is, add WebAssembly to
+ what it disables, and later consider having two new directives
+ which do each individually or something.
+
+ In all cases I throw an EvalError *before* other WebAssembly
+ errors would be produced.
+
+ Note that, as for eval, reporting doesn't work and is tracked by
+ https://webkit.org/b/111869
+
+ * runtime/JSGlobalObject.cpp:
+ (JSC::JSGlobalObject::JSGlobalObject):
+ * runtime/JSGlobalObject.h:
+ (JSC::JSGlobalObject::webAssemblyEnabled):
+ (JSC::JSGlobalObject::webAssemblyDisabledErrorMessage):
+ (JSC::JSGlobalObject::setWebAssemblyEnabled):
+ * wasm/js/JSWebAssemblyInstance.cpp:
+ (JSC::JSWebAssemblyInstance::create):
+ * wasm/js/JSWebAssemblyMemory.cpp:
+ (JSC::JSWebAssemblyMemory::create):
+ * wasm/js/JSWebAssemblyMemory.h:
+ * wasm/js/JSWebAssemblyTable.cpp:
+ (JSC::JSWebAssemblyTable::create):
+ * wasm/js/WebAssemblyMemoryConstructor.cpp:
+ (JSC::constructJSWebAssemblyMemory):
+
2017-06-28 Keith Miller <[email protected]>
VMTraps has some races
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (218950 => 218951)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp 2017-06-29 18:49:18 UTC (rev 218951)
@@ -330,9 +330,7 @@
, m_setAddWatchpoint(IsWatched)
, m_arraySpeciesWatchpoint(ClearWatchpoint)
, m_templateRegistry(vm)
- , m_evalEnabled(true)
, m_runtimeFlags()
- , m_consoleClient(nullptr)
, m_globalObjectMethodTable(globalObjectMethodTable ? globalObjectMethodTable : &s_globalObjectMethodTable)
{
}
Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (218950 => 218951)
--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h 2017-06-29 18:49:18 UTC (rev 218951)
@@ -441,10 +441,12 @@
TemplateRegistry m_templateRegistry;
- bool m_evalEnabled;
+ bool m_evalEnabled { true };
+ bool m_webAssemblyEnabled { true };
String m_evalDisabledErrorMessage;
+ String m_webAssemblyDisabledErrorMessage;
RuntimeFlags m_runtimeFlags;
- ConsoleClient* m_consoleClient;
+ ConsoleClient* m_consoleClient { nullptr };
static JS_EXPORTDATA const GlobalObjectMethodTable s_globalObjectMethodTable;
const GlobalObjectMethodTable* m_globalObjectMethodTable;
@@ -799,12 +801,19 @@
void queueMicrotask(Ref<Microtask>&&);
bool evalEnabled() const { return m_evalEnabled; }
+ bool webAssemblyEnabled() const { return m_webAssemblyEnabled; }
const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
+ const String& webAssemblyDisabledErrorMessage() const { return m_webAssemblyDisabledErrorMessage; }
void setEvalEnabled(bool enabled, const String& errorMessage = String())
{
m_evalEnabled = enabled;
m_evalDisabledErrorMessage = errorMessage;
}
+ void setWebAssemblyEnabled(bool enabled, const String& errorMessage = String())
+ {
+ m_webAssemblyEnabled = enabled;
+ m_webAssemblyDisabledErrorMessage = errorMessage;
+ }
void resetPrototype(VM&, JSValue prototype);
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp (218950 => 218951)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyInstance.cpp 2017-06-29 18:49:18 UTC (rev 218951)
@@ -141,6 +141,9 @@
return nullptr;
};
+ if (!globalObject->webAssemblyEnabled())
+ return exception(createEvalError(exec, globalObject->webAssemblyDisabledErrorMessage()));
+
auto importFailMessage = [&] (const Wasm::Import& import, const char* before, const char* after) {
return makeString(before, " ", String::fromUTF8(import.module), ":", String::fromUTF8(import.field), " ", after);
};
@@ -319,7 +322,7 @@
return exception(createOutOfMemoryError(exec));
instance->m_memory.set(vm, instance,
- JSWebAssemblyMemory::create(vm, exec->lexicalGlobalObject()->WebAssemblyMemoryStructure(), memory.releaseNonNull()));
+ JSWebAssemblyMemory::create(exec, vm, exec->lexicalGlobalObject()->WebAssemblyMemoryStructure(), memory.releaseNonNull()));
RETURN_IF_EXCEPTION(throwScope, nullptr);
}
}
@@ -345,7 +348,8 @@
if (!instance->memory()) {
// Make sure we have a dummy memory, so that wasm -> wasm thunks avoid checking for a nullptr Memory when trying to set pinned registers.
- instance->m_memory.set(vm, instance, JSWebAssemblyMemory::create(vm, exec->lexicalGlobalObject()->WebAssemblyMemoryStructure(), adoptRef(*(new Wasm::Memory()))));
+ instance->m_memory.set(vm, instance, JSWebAssemblyMemory::create(exec, vm, exec->lexicalGlobalObject()->WebAssemblyMemoryStructure(), adoptRef(*(new Wasm::Memory()))));
+ RETURN_IF_EXCEPTION(throwScope, nullptr);
}
// Globals
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyMemory.cpp (218950 => 218951)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyMemory.cpp 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyMemory.cpp 2017-06-29 18:49:18 UTC (rev 218951)
@@ -37,8 +37,19 @@
const ClassInfo JSWebAssemblyMemory::s_info = { "WebAssembly.Memory", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSWebAssemblyMemory) };
-JSWebAssemblyMemory* JSWebAssemblyMemory::create(VM& vm, Structure* structure, Ref<Wasm::Memory>&& memory)
+JSWebAssemblyMemory* JSWebAssemblyMemory::create(ExecState* exec, VM& vm, Structure* structure, Ref<Wasm::Memory>&& memory)
{
+ auto throwScope = DECLARE_THROW_SCOPE(vm);
+ auto* globalObject = exec->lexicalGlobalObject();
+
+ auto exception = [&] (JSObject* error) {
+ throwException(exec, throwScope, error);
+ return nullptr;
+ };
+
+ if (!globalObject->webAssemblyEnabled())
+ return exception(createEvalError(exec, globalObject->webAssemblyDisabledErrorMessage()));
+
auto* instance = new (NotNull, allocateCell<JSWebAssemblyMemory>(vm.heap)) JSWebAssemblyMemory(vm, structure, WTFMove(memory));
instance->m_memory->check();
instance->finishCreation(vm);
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyMemory.h (218950 => 218951)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyMemory.h 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyMemory.h 2017-06-29 18:49:18 UTC (rev 218951)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -41,7 +41,7 @@
public:
typedef JSDestructibleObject Base;
- static JSWebAssemblyMemory* create(VM&, Structure*, Ref<Wasm::Memory>&&);
+ static JSWebAssemblyMemory* create(ExecState*, VM&, Structure*, Ref<Wasm::Memory>&&);
static Structure* createStructure(VM&, JSGlobalObject*, JSValue);
DECLARE_EXPORT_INFO;
Modified: trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.cpp (218950 => 218951)
--- trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.cpp 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/_javascript_Core/wasm/js/JSWebAssemblyTable.cpp 2017-06-29 18:49:18 UTC (rev 218951)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -39,11 +39,19 @@
JSWebAssemblyTable* JSWebAssemblyTable::create(ExecState* exec, VM& vm, Structure* structure, uint32_t initial, std::optional<uint32_t> maximum)
{
auto throwScope = DECLARE_THROW_SCOPE(vm);
- if (!isValidSize(initial)) {
- throwException(exec, throwScope, createOutOfMemoryError(exec));
+ auto* globalObject = exec->lexicalGlobalObject();
+
+ auto exception = [&] (JSObject* error) {
+ throwException(exec, throwScope, error);
return nullptr;
- }
+ };
+ if (!globalObject->webAssemblyEnabled())
+ return exception(createEvalError(exec, globalObject->webAssemblyDisabledErrorMessage()));
+
+ if (!isValidSize(initial))
+ return exception(createOutOfMemoryError(exec));
+
auto* instance = new (NotNull, allocateCell<JSWebAssemblyTable>(vm.heap)) JSWebAssemblyTable(vm, structure, initial, maximum);
instance->finishCreation(vm);
return instance;
Modified: trunk/Source/_javascript_Core/wasm/js/WebAssemblyMemoryConstructor.cpp (218950 => 218951)
--- trunk/Source/_javascript_Core/wasm/js/WebAssemblyMemoryConstructor.cpp 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/_javascript_Core/wasm/js/WebAssemblyMemoryConstructor.cpp 2017-06-29 18:49:18 UTC (rev 218951)
@@ -100,7 +100,10 @@
if (!memory)
return JSValue::encode(throwException(exec, throwScope, createOutOfMemoryError(exec)));
- return JSValue::encode(JSWebAssemblyMemory::create(vm, exec->lexicalGlobalObject()->WebAssemblyMemoryStructure(), adoptRef(*memory.leakRef())));
+ auto* jsMemory = JSWebAssemblyMemory::create(exec, vm, exec->lexicalGlobalObject()->WebAssemblyMemoryStructure(), adoptRef(*memory.leakRef()));
+ RETURN_IF_EXCEPTION(throwScope, encodedJSValue());
+
+ return JSValue::encode(jsMemory);
}
static EncodedJSValue JSC_HOST_CALL callJSWebAssemblyMemory(ExecState* exec)
Modified: trunk/Source/WebCore/ChangeLog (218950 => 218951)
--- trunk/Source/WebCore/ChangeLog 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/WebCore/ChangeLog 2017-06-29 18:49:18 UTC (rev 218951)
@@ -1,3 +1,49 @@
+2017-06-29 JF Bastien <[email protected]>
+
+ WebAssembly: disable some APIs under CSP
+ https://bugs.webkit.org/show_bug.cgi?id=173892
+ <rdar://problem/32914613>
+
+ Reviewed by Daniel Bates.
+
+ This does the basic separation of eval-blocked and
+ WebAssembly-blocked, but currently only blocks neither or both. I
+ think we'll eventually consider allowing one to be blocked but not
+ the other, so this separation makes sense and means that when we
+ want to do the change it'll be tiny. At a minimum we want a
+ different error message, which this patch provides (a lot of the
+ code ties blocking to the error message).
+
+ Tests: http/tests/security/contentSecurityPolicy/WebAssembly-allowed.html
+ http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-about-blank-iframe.html
+ http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-external-script.html
+ http/tests/security/contentSecurityPolicy/WebAssembly-blocked-in-subframe.html
+ http/tests/security/contentSecurityPolicy/WebAssembly-blocked.html
+
+ * bindings/js/ScriptController.cpp:
+ (WebCore::ScriptController::enableWebAssembly):
+ (WebCore::ScriptController::disableWebAssembly):
+ * bindings/js/ScriptController.h:
+ * bindings/js/WorkerScriptController.cpp:
+ (WebCore::WorkerScriptController::disableWebAssembly):
+ * bindings/js/WorkerScriptController.h:
+ * dom/Document.cpp:
+ (WebCore::Document::disableWebAssembly):
+ * dom/Document.h:
+ * dom/ScriptExecutionContext.h:
+ * page/csp/ContentSecurityPolicy.cpp:
+ (WebCore::ContentSecurityPolicy::didCreateWindowProxy):
+ (WebCore::ContentSecurityPolicy::applyPolicyToScriptExecutionContext):
+ * page/csp/ContentSecurityPolicy.h:
+ * page/csp/ContentSecurityPolicyDirectiveList.cpp:
+ (WebCore::ContentSecurityPolicyDirectiveList::create):
+ * page/csp/ContentSecurityPolicyDirectiveList.h:
+ (WebCore::ContentSecurityPolicyDirectiveList::webAssemblyDisabledErrorMessage):
+ (WebCore::ContentSecurityPolicyDirectiveList::setWebAssemblyDisabledErrorMessage):
+ * workers/WorkerGlobalScope.cpp:
+ (WebCore::WorkerGlobalScope::disableWebAssembly):
+ * workers/WorkerGlobalScope.h:
+
2017-06-29 Zalan Bujtas <[email protected]>
Make InlineBox::m_topLeft and m_logicalWidth protected.
Modified: trunk/Source/WebCore/bindings/js/ScriptController.cpp (218950 => 218951)
--- trunk/Source/WebCore/bindings/js/ScriptController.cpp 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/WebCore/bindings/js/ScriptController.cpp 2017-06-29 18:49:18 UTC (rev 218951)
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999-2001 Harri Porten ([email protected])
* Copyright (C) 2001 Peter Kelly ([email protected])
- * Copyright (C) 2006-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -446,6 +446,14 @@
windowProxy->window()->setEvalEnabled(true);
}
+void ScriptController::enableWebAssembly()
+{
+ auto* windowProxy = existingWindowProxy(mainThreadNormalWorld());
+ if (!windowProxy)
+ return;
+ windowProxy->window()->setWebAssemblyEnabled(true);
+}
+
void ScriptController::disableEval(const String& errorMessage)
{
auto* windowProxy = existingWindowProxy(mainThreadNormalWorld());
@@ -454,6 +462,14 @@
windowProxy->window()->setEvalEnabled(false, errorMessage);
}
+void ScriptController::disableWebAssembly(const String& errorMessage)
+{
+ auto* windowProxy = existingWindowProxy(mainThreadNormalWorld());
+ if (!windowProxy)
+ return;
+ windowProxy->window()->setWebAssemblyEnabled(false, errorMessage);
+}
+
bool ScriptController::processingUserGesture()
{
return UserGestureIndicator::processingUserGesture();
Modified: trunk/Source/WebCore/bindings/js/ScriptController.h (218950 => 218951)
--- trunk/Source/WebCore/bindings/js/ScriptController.h 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/WebCore/bindings/js/ScriptController.h 2017-06-29 18:49:18 UTC (rev 218951)
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 Harri Porten ([email protected])
* Copyright (C) 2001 Peter Kelly ([email protected])
- * Copyright (C) 2008-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
* Copyright (C) 2008 Eric Seidel <[email protected]>
*
* This library is free software; you can redistribute it and/or
@@ -129,7 +129,9 @@
WTF::TextPosition eventHandlerPosition() const;
void enableEval();
+ void enableWebAssembly();
void disableEval(const String& errorMessage);
+ void disableWebAssembly(const String& errorMessage);
WEBCORE_EXPORT static bool processingUserGesture();
WEBCORE_EXPORT static bool processingUserGestureForMedia();
Modified: trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp (218950 => 218951)
--- trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/WebCore/bindings/js/WorkerScriptController.cpp 2017-06-29 18:49:18 UTC (rev 218951)
@@ -187,11 +187,19 @@
void WorkerScriptController::disableEval(const String& errorMessage)
{
initScriptIfNeeded();
- JSLockHolder lock(vm());
+ JSLockHolder lock{vm()};
m_workerGlobalScopeWrapper->setEvalEnabled(false, errorMessage);
}
+void WorkerScriptController::disableWebAssembly(const String& errorMessage)
+{
+ initScriptIfNeeded();
+ JSLockHolder lock{vm()};
+
+ m_workerGlobalScopeWrapper->setWebAssemblyEnabled(false, errorMessage);
+}
+
void WorkerScriptController::releaseHeapAccess()
{
m_vm->heap.releaseAccess();
Modified: trunk/Source/WebCore/bindings/js/WorkerScriptController.h (218950 => 218951)
--- trunk/Source/WebCore/bindings/js/WorkerScriptController.h 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/WebCore/bindings/js/WorkerScriptController.h 2017-06-29 18:49:18 UTC (rev 218951)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2015, 2016 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
* Copyright (C) 2012 Google Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -75,6 +75,7 @@
bool isExecutionForbidden() const;
void disableEval(const String& errorMessage);
+ void disableWebAssembly(const String& errorMessage);
JSC::VM& vm() { return *m_vm; }
Modified: trunk/Source/WebCore/dom/Document.cpp (218950 => 218951)
--- trunk/Source/WebCore/dom/Document.cpp 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/WebCore/dom/Document.cpp 2017-06-29 18:49:18 UTC (rev 218951)
@@ -3066,6 +3066,14 @@
frame()->script().disableEval(errorMessage);
}
+void Document::disableWebAssembly(const String& errorMessage)
+{
+ if (!frame())
+ return;
+
+ frame()->script().disableWebAssembly(errorMessage);
+}
+
#if ENABLE(INDEXED_DATABASE)
IDBClient::IDBConnectionProxy* Document::idbConnectionProxy()
Modified: trunk/Source/WebCore/dom/Document.h (218950 => 218951)
--- trunk/Source/WebCore/dom/Document.h 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/WebCore/dom/Document.h 2017-06-29 18:49:18 UTC (rev 218951)
@@ -658,6 +658,7 @@
String userAgent(const URL&) const final;
void disableEval(const String& errorMessage) final;
+ void disableWebAssembly(const String& errorMessage) final;
#if ENABLE(INDEXED_DATABASE)
IDBClient::IDBConnectionProxy* idbConnectionProxy() final;
Modified: trunk/Source/WebCore/dom/ScriptExecutionContext.h (218950 => 218951)
--- trunk/Source/WebCore/dom/ScriptExecutionContext.h 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/WebCore/dom/ScriptExecutionContext.h 2017-06-29 18:49:18 UTC (rev 218951)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009, 2010, 2011, 2013, 2014, 2015, 2016 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
* Copyright (C) 2012 Google Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -85,6 +85,7 @@
virtual String userAgent(const URL&) const = 0;
virtual void disableEval(const String& errorMessage) = 0;
+ virtual void disableWebAssembly(const String& errorMessage) = 0;
#if ENABLE(INDEXED_DATABASE)
virtual IDBClient::IDBConnectionProxy* idbConnectionProxy() = 0;
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp (218950 => 218951)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp 2017-06-29 18:49:18 UTC (rev 218951)
@@ -159,6 +159,7 @@
return;
}
window->setEvalEnabled(m_lastPolicyEvalDisabledErrorMessage.isNull(), m_lastPolicyEvalDisabledErrorMessage);
+ window->setWebAssemblyEnabled(m_lastPolicyWebAssemblyDisabledErrorMessage.isNull(), m_lastPolicyWebAssemblyDisabledErrorMessage);
}
ContentSecurityPolicyResponseHeaders ContentSecurityPolicy::responseHeaders() const
@@ -230,8 +231,10 @@
bool enableStrictMixedContentMode = false;
for (auto& policy : m_policies) {
const ContentSecurityPolicyDirective* violatedDirective = policy->violatedDirectiveForUnsafeEval();
- if (violatedDirective && !violatedDirective->directiveList().isReportOnly())
+ if (violatedDirective && !violatedDirective->directiveList().isReportOnly()) {
m_lastPolicyEvalDisabledErrorMessage = policy->evalDisabledErrorMessage();
+ m_lastPolicyWebAssemblyDisabledErrorMessage = policy->webAssemblyDisabledErrorMessage();
+ }
if (policy->hasBlockAllMixedContentDirective() && !policy->isReportOnly())
enableStrictMixedContentMode = true;
}
@@ -238,6 +241,8 @@
if (!m_lastPolicyEvalDisabledErrorMessage.isNull())
m_scriptExecutionContext->disableEval(m_lastPolicyEvalDisabledErrorMessage);
+ if (!m_lastPolicyWebAssemblyDisabledErrorMessage.isNull())
+ m_scriptExecutionContext->disableWebAssembly(m_lastPolicyWebAssemblyDisabledErrorMessage);
if (m_sandboxFlags != SandboxNone && is<Document>(m_scriptExecutionContext))
m_scriptExecutionContext->enforceSandboxFlags(m_sandboxFlags);
if (enableStrictMixedContentMode)
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h (218950 => 218951)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h 2017-06-29 18:49:18 UTC (rev 218951)
@@ -207,6 +207,7 @@
String m_selfSourceProtocol;
CSPDirectiveListVector m_policies;
String m_lastPolicyEvalDisabledErrorMessage;
+ String m_lastPolicyWebAssemblyDisabledErrorMessage;
SandboxFlags m_sandboxFlags;
bool m_overrideInlineStyleAllowed { false };
bool m_isReportingEnabled { true };
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp (218950 => 218951)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.cpp 2017-06-29 18:49:18 UTC (rev 218951)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -109,8 +109,10 @@
directives->parse(header, from);
if (!checkEval(directives->operativeDirective(directives->m_scriptSrc.get()))) {
- String message = makeString("Refused to evaluate a string as _javascript_ because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"", directives->operativeDirective(directives->m_scriptSrc.get())->text(), "\".\n");
- directives->setEvalDisabledErrorMessage(message);
+ String evalDisabledMessage = makeString("Refused to evaluate a string as _javascript_ because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"", directives->operativeDirective(directives->m_scriptSrc.get())->text(), "\".\n");
+ directives->setEvalDisabledErrorMessage(evalDisabledMessage);
+ String webAssemblyDisabledMessage = makeString("Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"", directives->operativeDirective(directives->m_scriptSrc.get())->text(), "\".\n");
+ directives->setWebAssemblyDisabledErrorMessage(webAssemblyDisabledMessage);
}
if (directives->isReportOnly() && directives->reportURIs().isEmpty())
Modified: trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h (218950 => 218951)
--- trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/WebCore/page/csp/ContentSecurityPolicyDirectiveList.h 2017-06-29 18:49:18 UTC (rev 218951)
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2011 Google, Inc. All rights reserved.
- * Copyright (C) 2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -74,6 +74,7 @@
bool hasBlockAllMixedContentDirective() const { return m_hasBlockAllMixedContentDirective; }
const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
+ const String& webAssemblyDisabledErrorMessage() const { return m_webAssemblyDisabledErrorMessage; }
bool isReportOnly() const { return m_reportOnly; }
const Vector<String>& reportURIs() const { return m_reportURIs; }
@@ -97,6 +98,7 @@
ContentSecurityPolicySourceListDirective* operativeDirective(ContentSecurityPolicySourceListDirective*) const;
void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisabledErrorMessage = errorMessage; }
+ void setWebAssemblyDisabledErrorMessage(const String& errorMessage) { m_webAssemblyDisabledErrorMessage = errorMessage; }
// FIXME: Make this a const reference once we teach applySandboxPolicy() to store its policy as opposed to applying it directly onto ContentSecurityPolicy.
ContentSecurityPolicy& m_policy;
@@ -127,6 +129,7 @@
Vector<String> m_reportURIs;
String m_evalDisabledErrorMessage;
+ String m_webAssemblyDisabledErrorMessage;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.cpp (218950 => 218951)
--- trunk/Source/WebCore/workers/WorkerGlobalScope.cpp 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.cpp 2017-06-29 18:49:18 UTC (rev 218951)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All Rights Reserved.
* Copyright (C) 2009, 2011 Google Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -152,6 +152,11 @@
m_script->disableEval(errorMessage);
}
+void WorkerGlobalScope::disableWebAssembly(const String& errorMessage)
+{
+ m_script->disableWebAssembly(errorMessage);
+}
+
#if ENABLE(WEB_SOCKETS)
SocketProvider* WorkerGlobalScope::socketProvider()
Modified: trunk/Source/WebCore/workers/WorkerGlobalScope.h (218950 => 218951)
--- trunk/Source/WebCore/workers/WorkerGlobalScope.h 2017-06-29 18:47:25 UTC (rev 218950)
+++ trunk/Source/WebCore/workers/WorkerGlobalScope.h 2017-06-29 18:49:18 UTC (rev 218951)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2016 Apple Inc. All rights reserved.
+ * Copyright (C) 2008-2017 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -134,6 +134,7 @@
URL completeURL(const String&) const final;
String userAgent(const URL&) const final;
void disableEval(const String& errorMessage) final;
+ void disableWebAssembly(const String& errorMessage) final;
EventTarget* errorEventTarget() final;
WorkerEventQueue& eventQueue() const final;
String resourceRequestIdentifier() const final { return m_identifier; }