Bug 976151 - Anti eval/Function() check during wrapping should use |subsumes|. r=gabor
authorBobby Holley <bobbyholley@gmail.com>
Tue, 25 Feb 2014 08:38:33 -0800
changeset 170517 9a8a8a73df7136fd6fa01a54db441b89bcbe1df3
parent 170516 63d96f3e3e42151cf563728599d569210f116928
child 170518 0a53f6e5853d364a789bb0dd804c6825935f560f
push id26291
push userkwierso@gmail.com
push dateWed, 26 Feb 2014 04:10:11 +0000
treeherdermozilla-central@626d99c084cb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgabor
bugs976151
milestone30.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 976151 - Anti eval/Function() check during wrapping should use |subsumes|. r=gabor
js/xpconnect/tests/unit/test_bug976151.js
js/xpconnect/tests/unit/xpcshell.ini
js/xpconnect/wrappers/WrapperFactory.cpp
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/unit/test_bug976151.js
@@ -0,0 +1,24 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const Cu = Components.utils;
+function run_test() {
+  let unprivilegedSb = new Cu.Sandbox('http://www.example.com');
+  function checkCantWrap(val) {
+    try {
+      unprivilegedSb.prop = val;
+      do_check_true(false);
+    } catch (e) {
+      do_check_true(/denied|insecure|/.test(e));
+    }
+  }
+  let xoSb = new Cu.Sandbox('http://www.example.net');
+  let epSb = new Cu.Sandbox(['http://www.example.com']);
+  checkCantWrap(eval);
+  checkCantWrap(xoSb.eval);
+  checkCantWrap(epSb.eval);
+  checkCantWrap(Function);
+  checkCantWrap(xoSb.Function);
+  checkCantWrap(epSb.Function);
+}
--- a/js/xpconnect/tests/unit/xpcshell.ini
+++ b/js/xpconnect/tests/unit/xpcshell.ini
@@ -35,16 +35,17 @@ support-files =
 [test_bug849730.js]
 [test_bug851895.js]
 [test_bug854558.js]
 [test_bug868675.js]
 [test_bug867486.js]
 [test_bug872772.js]
 [test_bug885800.js]
 [test_bug961054.js]
+[test_bug976151.js]
 [test_bug_442086.js]
 [test_file.js]
 [test_blob.js]
 [test_blob2.js]
 [test_file2.js]
 [test_import.js]
 [test_import_fail.js]
 [test_js_weak_references.js]
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -454,23 +454,23 @@ WrapperFactory::Rewrap(JSContext *cx, Ha
 
         // If Xrays are warranted, the caller may waive them for non-security
         // wrappers.
         bool waiveXrays = wantXrays && !securityWrapper && waiveXrayFlag;
 
         wrapper = SelectWrapper(securityWrapper, wantXrays, xrayType, waiveXrays);
     }
 
-    if (wrapper == &ChromeObjectWrapper::singleton) {
-        // This shouldn't happen, but do a quick check to make some dumb addon
-        // doesn't expose chrome eval or Function().
+    if (!targetSubsumesOrigin) {
+        // Do a belt-and-suspenders check against exposing eval()/Function() to
+        // non-subsuming content.
         JSFunction *fun = JS_GetObjectFunction(obj);
         if (fun) {
             if (JS_IsBuiltinEvalFunction(fun) || JS_IsBuiltinFunctionConstructor(fun)) {
-                JS_ReportError(cx, "Not allowed to access chrome eval or Function from content");
+                JS_ReportError(cx, "Permission denied to expose eval or Function to non-subsuming content");
                 return nullptr;
             }
         }
     }
 
     DEBUG_CheckUnwrapSafety(obj, wrapper, origin, target);
 
     if (existing)