changeset 527:6ef6f65f0cd0

7046823: vulnerability with rhino javascript engine Reviewed-by: sundar
author asaha
date Thu, 21 Jul 2011 17:18:32 -0700
parents 5b47d8bda9b0
children ce3948d79810
files src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java src/share/classes/com/sun/script/javascript/RhinoTopLevel.java
diffstat 2 files changed, 60 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java	Tue Jul 19 10:41:32 2011 -0700
+++ b/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java	Thu Jul 21 17:18:32 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 import sun.org.mozilla.javascript.internal.*;
 import java.lang.reflect.Method;
 import java.io.*;
+import java.security.*;
 import java.util.*;
 
 
@@ -45,6 +46,8 @@
 
     private static final boolean DEBUG = false;
 
+    private AccessControlContext accCtxt;
+
     /* Scope where standard JavaScript objects and our
      * extensions to it are stored. Note that these are not
      * user defined engine level global variables. These are
@@ -63,6 +66,10 @@
 
     static {
         ContextFactory.initGlobal(new ContextFactory() {
+            /**
+             * Create new Context instance to be associated with the current thread.
+             */
+            @Override
             protected Context makeContext() {
                 Context cx = super.makeContext();
                 cx.setClassShutter(RhinoClassShutter.getInstance());
@@ -70,6 +77,41 @@
                 return cx;
             }
 
+
+            /**
+             * Execute top call to script or function. When the runtime is about to 
+             * execute a script or function that will create the first stack frame 
+             * with scriptable code, it calls this method to perform the real call. 
+             * In this way execution of any script happens inside this function.
+             */
+            @Override
+            protected Object doTopCall(final Callable callable,
+                               final Context cx, final Scriptable scope,
+                               final Scriptable thisObj, final Object[] args) {
+                AccessControlContext accCtxt = null;
+                Scriptable global = ScriptableObject.getTopLevelScope(scope);
+                Scriptable globalProto = global.getPrototype();
+                if (globalProto instanceof RhinoTopLevel) {
+                    accCtxt = ((RhinoTopLevel)globalProto).getAccessContext();
+                }
+
+                if (accCtxt != null) {
+                    return AccessController.doPrivileged(new PrivilegedAction<Object>() {
+                        public Object run() {
+                            return superDoTopCall(callable, cx, scope, thisObj, args);
+                        }
+                    }, accCtxt);
+                } else {
+                    return superDoTopCall(callable, cx, scope, thisObj, args);
+                }
+            }
+
+            private  Object superDoTopCall(Callable callable,
+                               Context cx, Scriptable scope,
+                               Scriptable thisObj, Object[] args) {
+                return super.doTopCall(callable, cx, scope, thisObj, args);
+            }
+
             public boolean hasFeature(Context cx, int feature) {
                 // we do not support E4X (ECMAScript for XML)!
                 if (feature == Context.FEATURE_E4X) {
@@ -87,6 +129,10 @@
      */
     public RhinoScriptEngine() {
 
+        if (System.getSecurityManager() != null) {
+            accCtxt = AccessController.getContext();
+        }
+
         Context cx = enterContext();
         try {
             topLevel = new RhinoTopLevel(cx, this);
@@ -314,6 +360,10 @@
         factory = fac;
     }
 
+    AccessControlContext getAccessContext() {
+        return accCtxt;
+    }
+
     Object[] wrapArguments(Object[] args) {
         if (args == null) {
             return Context.emptyArgs;
--- a/src/share/classes/com/sun/script/javascript/RhinoTopLevel.java	Tue Jul 19 10:41:32 2011 -0700
+++ b/src/share/classes/com/sun/script/javascript/RhinoTopLevel.java	Thu Jul 21 17:18:32 2011 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -47,7 +47,10 @@
                 "var org = Packages.org;                   \n";
 
     RhinoTopLevel(Context cx, RhinoScriptEngine engine) {
-        super(cx);
+        // second boolean parameter to super constructor tells whether
+        // to seal standard JavaScript objects or not. If security manager
+        // is present, we seal the standard objects.
+        super(cx, System.getSecurityManager() != null);
         this.engine = engine;
 
 
@@ -164,5 +167,9 @@
         return engine;
     }
 
+    AccessControlContext getAccessContext() {
+        return engine.getAccessContext();
+    }
+
     private RhinoScriptEngine engine;
 }