# HG changeset patch # User andrew # Date 1318550096 -3600 # Node ID fc3acc1b4e5560ea9832a9ec8955a4fbb7172b95 # Parent 63bbe6780dd3f3ffda3d0f57165702ed36d89a62 7046823, CVE-2011-3544: missing SecurityManager checks in scripting engine diff -r 63bbe6780dd3 -r fc3acc1b4e55 src/share/classes/com/sun/script/javascript/RhinoScriptEngine.java --- 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() { + 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; diff -r 63bbe6780dd3 -r fc3acc1b4e55 src/share/classes/com/sun/script/javascript/RhinoTopLevel.java --- 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; }