Catch chrome eval escaping into content (bug 625559, r=gal).
authorBlake Kaplan <mrbkap@gmail.com>
Wed, 26 Jan 2011 18:28:49 -0800
changeset 61448 9ac5cb7a9aeea5bdeb8782cb87a1c5e6d68311fd
parent 61447 53dea513311e6b915b229cf2f8d784b3cc482559
child 61449 0a28e819fb0aa7a6140a8a3723ef105ac14eefd0
push idunknown
push userunknown
push dateunknown
reviewersgal
bugs625559
milestone2.0b10pre
Catch chrome eval escaping into content (bug 625559, r=gal).
js/src/jsfun.cpp
js/src/jsfun.h
js/src/xpconnect/wrappers/WrapperFactory.cpp
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -2599,16 +2599,26 @@ Function(JSContext *cx, uintN argc, Valu
     const jschar *chars = str->getChars(cx);
     if (!chars)
         return JS_FALSE;
 
     return Compiler::compileFunctionBody(cx, fun, principals, &bindings,
                                          chars, length, filename, lineno);
 }
 
+namespace js {
+
+bool
+IsBuiltinFunctionConstructor(JSFunction *fun)
+{
+    return fun->maybeNative() == Function;
+}
+
+}
+
 static JSBool
 ThrowTypeError(JSContext *cx, uintN argc, Value *vp)
 {
     JS_ReportErrorFlagsAndNumber(cx, JSREPORT_ERROR, js_GetErrorMessage, NULL,
                                  JSMSG_THROW_TYPE_ERROR);
     return false;
 }
 
--- a/js/src/jsfun.h
+++ b/js/src/jsfun.h
@@ -424,16 +424,19 @@ IsConstructing_PossiblyWithGivenThisObje
 inline const char *
 GetFunctionNameBytes(JSContext *cx, JSFunction *fun, JSAutoByteString *bytes)
 {
     if (fun->atom)
         return bytes->encode(cx, ATOM_TO_STRING(fun->atom));
     return js_anonymous_str;
 }
 
+bool
+IsBuiltinFunctionConstructor(JSFunction *fun);
+
 } /* namespace js */
 
 extern JSString *
 fun_toStringHelper(JSContext *cx, JSObject *obj, uintN indent);
 
 extern JSFunction *
 js_NewFunction(JSContext *cx, JSObject *funobj, js::Native native, uintN nargs,
                uintN flags, JSObject *parent, JSAtom *atom);
--- a/js/src/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/src/xpconnect/wrappers/WrapperFactory.cpp
@@ -259,16 +259,23 @@ WrapperFactory::Rewrap(JSContext *cx, JS
                 xrayHolder = Xray::createHolder(cx, obj, parent);
                 if (!xrayHolder)
                     return nsnull;
             } else {
                 wrapper = &JSCrossCompartmentWrapper::singleton;
             }
         }
     } else if (AccessCheck::isChrome(origin)) {
+        if (obj->isFunction()) {
+            JSFunction *fun = obj->getFunctionPrivate();
+            if (js::IsBuiltinEvalFunction(fun) || js::IsBuiltinFunctionConstructor(fun)) {
+                JS_ReportError(cx, "Not allowed to access chrome eval or Function from content");
+                return nsnull;
+            }
+        }
         wrapper = &FilteringWrapper<JSCrossCompartmentWrapper,
                                     ExposedPropertiesOnly>::singleton;
     } else if (AccessCheck::isSameOrigin(origin, target)) {
         // Same origin we use a transparent wrapper, unless the compartment asks
         // for an Xray or the wrapper needs a SOW.
         if (AccessCheck::needsSystemOnlyWrapper(obj)) {
             wrapper = &FilteringWrapper<JSCrossCompartmentWrapper,
                                         OnlyIfSubjectIsSystem>::singleton;