changeset 4570:fc3acc1b4e55

7046823, CVE-2011-3544: missing SecurityManager checks in scripting engine
author andrew
date Fri, 14 Oct 2011 00:54:56 +0100
parents 63bbe6780dd3
children 8ebc1115d725
files src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java src/share/classes/com/sun/script/javascript/RhinoTopLevel.java
diffstat 2 files changed, 59 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java	Fri Oct 14 00:50:59 2011 +0100
+++ b/src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java	Fri Oct 14 00:54:56 2011 +0100
@@ -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
@@ -65,6 +68,10 @@
     private static final int optimizationLevel = getOptimizationLevel();
     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.setLanguageVersion(languageVersion);
@@ -73,6 +80,40 @@
                 cx.setWrapFactory(RhinoWrapFactory.getInstance());
                 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);
+            }
         });
     }
 
@@ -104,6 +145,10 @@
      */
     public RhinoScriptEngine() {
 
+        if (System.getSecurityManager() != null) {
+            accCtxt = AccessController.getContext();
+        }
+
         Context cx = enterContext();
         try {
             topLevel = new RhinoTopLevel(cx, this);
@@ -360,6 +405,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	Fri Oct 14 00:50:59 2011 +0100
+++ b/src/share/classes/com/sun/script/javascript/RhinoTopLevel.java	Fri Oct 14 00:54:56 2011 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, 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
@@ -26,6 +26,7 @@
 package com.sun.script.javascript;
 
 import sun.org.mozilla.javascript.internal.*;
+import java.security.AccessControlContext;
 import javax.script.*;
 
 /**
@@ -38,7 +39,10 @@
  */
 public final class RhinoTopLevel extends ImporterTopLevel {
     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;
 
 
@@ -152,5 +156,9 @@
         return engine;
     }
 
+    AccessControlContext getAccessContext() {
+        return engine.getAccessContext();
+    }
+
     private RhinoScriptEngine engine;
 }