Fri, 04 Oct 2013 16:21:29 +0530
8025771: Enhance Nashorn Contexts
Reviewed-by: jlaskey, hannesw
1.1 --- a/make/java.security.override Tue Oct 01 14:38:56 2013 +0530 1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 1.3 @@ -1,14 +0,0 @@ 1.4 -# We would like to avoid references from anywhere outside nashorn 1.5 -# to codegen, IR and parser packages, in particular script generated classes. 1.6 -# We ensure that by overriding "package.access" security property. 1.7 - 1.8 -# The following "package.access" value was copied from default java.security 1.9 -# of jre/lib/security and appended with nashorn sensitive packages. 1.10 - 1.11 -# 1.12 -# List of comma-separated packages that start with or equal this string 1.13 -# will cause a security exception to be thrown when 1.14 -# passed to checkPackageAccess unless the 1.15 -# corresponding RuntimePermission ("accessClassInPackage."+package) has 1.16 -# been granted. 1.17 -package.access=sun.,com.sun.xml.internal.ws.,com.sun.xml.internal.bind.,com.sun.imageio.,com.sun.org.apache.xerces.internal.utils.,com.sun.org.apache.xalan.internal.utils.,com.sun.org.glassfish.external.,com.sun.org.glassfish.gmbal.,jdk.internal.,jdk.nashorn.internal.,jdk.nashorn.tools.
2.1 --- a/make/project.properties Tue Oct 01 14:38:56 2013 +0530 2.2 +++ b/make/project.properties Fri Oct 04 16:21:29 2013 +0530 2.3 @@ -234,7 +234,7 @@ 2.4 #-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M 2.5 run.test.jvmargs.octane.main=${run.test.jvmargs.common} 2.6 2.7 -run.test.jvmsecurityargs=-Xverify:all -Djava.security.properties=${basedir}/make/java.security.override -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy 2.8 +run.test.jvmsecurityargs=-Xverify:all -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy 2.9 2.10 # VM options for script tests with @fork option 2.11 test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} ${run.test.jvmsecurityargs}
3.1 --- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Tue Oct 01 14:38:56 2013 +0530 3.2 +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Fri Oct 04 16:21:29 2013 +0530 3.3 @@ -313,7 +313,7 @@ 3.4 if (! Modifier.isPublic(clazz.getModifiers())) { 3.5 throw new SecurityException(getMessage("implementing.non.public.interface", clazz.getName())); 3.6 } 3.7 - Context.checkPackageAccess(clazz.getName()); 3.8 + Context.checkPackageAccess(clazz); 3.9 } 3.10 3.11 ScriptObject realSelf = null;
4.1 --- a/src/jdk/nashorn/internal/runtime/Context.java Tue Oct 01 14:38:56 2013 +0530 4.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java Fri Oct 04 16:21:29 2013 +0530 4.3 @@ -620,36 +620,53 @@ 4.4 } 4.5 4.6 /** 4.7 - * Checks that the given package can be accessed from no permissions context. 4.8 + * Checks that the given Class can be accessed from no permissions context. 4.9 * 4.10 - * @param fullName fully qualified package name 4.11 + * @param clazz Class object 4.12 * @throw SecurityException if not accessible 4.13 */ 4.14 - public static void checkPackageAccess(final String fullName) { 4.15 - final int index = fullName.lastIndexOf('.'); 4.16 - if (index != -1) { 4.17 - final SecurityManager sm = System.getSecurityManager(); 4.18 - if (sm != null) { 4.19 - AccessController.doPrivileged(new PrivilegedAction<Void>() { 4.20 - @Override 4.21 - public Void run() { 4.22 - sm.checkPackageAccess(fullName.substring(0, index)); 4.23 - return null; 4.24 - } 4.25 - }, NO_PERMISSIONS_ACC_CTXT); 4.26 + public static void checkPackageAccess(final Class clazz) { 4.27 + final SecurityManager sm = System.getSecurityManager(); 4.28 + if (sm != null) { 4.29 + Class bottomClazz = clazz; 4.30 + while(bottomClazz.isArray()) { 4.31 + bottomClazz = bottomClazz.getComponentType(); 4.32 } 4.33 + checkPackageAccess(sm, bottomClazz.getName()); 4.34 } 4.35 } 4.36 4.37 /** 4.38 * Checks that the given package can be accessed from no permissions context. 4.39 * 4.40 + * @param sm current security manager instance 4.41 * @param fullName fully qualified package name 4.42 + * @throw SecurityException if not accessible 4.43 + */ 4.44 + private static void checkPackageAccess(final SecurityManager sm, final String fullName) { 4.45 + sm.getClass(); // null check 4.46 + final int index = fullName.lastIndexOf('.'); 4.47 + if (index != -1) { 4.48 + final String pkgName = fullName.substring(0, index); 4.49 + AccessController.doPrivileged(new PrivilegedAction<Void>() { 4.50 + @Override 4.51 + public Void run() { 4.52 + sm.checkPackageAccess(pkgName); 4.53 + return null; 4.54 + } 4.55 + }, NO_PERMISSIONS_ACC_CTXT); 4.56 + } 4.57 + } 4.58 + 4.59 + /** 4.60 + * Checks that the given Class can be accessed from no permissions context. 4.61 + * 4.62 + * @param clazz Class object 4.63 * @return true if package is accessible, false otherwise 4.64 */ 4.65 - public static boolean isAccessiblePackage(final String fullName) { 4.66 + private static boolean isAccessiblePackage(final Class clazz) { 4.67 try { 4.68 - checkPackageAccess(fullName); 4.69 + checkPackageAccess(clazz); 4.70 return true; 4.71 } catch (final SecurityException se) { 4.72 return false; 4.73 @@ -663,7 +680,7 @@ 4.74 * @return true if Class is accessible, false otherwise 4.75 */ 4.76 public static boolean isAccessibleClass(final Class<?> clazz) { 4.77 - return Modifier.isPublic(clazz.getModifiers()) && Context.isAccessiblePackage(clazz.getName()); 4.78 + return Modifier.isPublic(clazz.getModifiers()) && Context.isAccessiblePackage(clazz); 4.79 } 4.80 4.81 /** 4.82 @@ -677,8 +694,16 @@ 4.83 * @throws ClassNotFoundException if class cannot be resolved 4.84 */ 4.85 public Class<?> findClass(final String fullName) throws ClassNotFoundException { 4.86 + if (fullName.indexOf('[') != -1 || fullName.indexOf('/') != -1) { 4.87 + // don't allow array class names or internal names. 4.88 + throw new ClassNotFoundException(fullName); 4.89 + } 4.90 + 4.91 // check package access as soon as possible! 4.92 - checkPackageAccess(fullName); 4.93 + final SecurityManager sm = System.getSecurityManager(); 4.94 + if (sm != null) { 4.95 + checkPackageAccess(sm, fullName); 4.96 + } 4.97 4.98 // try the script -classpath loader, if that is set 4.99 if (classPathLoader != null) {
5.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java Tue Oct 01 14:38:56 2013 +0530 5.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java Fri Oct 04 16:21:29 2013 +0530 5.3 @@ -109,7 +109,7 @@ 5.4 if (sm != null) { 5.5 for (Class<?> type : types) { 5.6 // check for restricted package access 5.7 - Context.checkPackageAccess(type.getName()); 5.8 + Context.checkPackageAccess(type); 5.9 } 5.10 } 5.11 return getAdapterInfo(types).getAdapterClassFor(classOverrides);
6.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java Tue Oct 01 14:38:56 2013 +0530 6.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java Fri Oct 04 16:21:29 2013 +0530 6.3 @@ -70,7 +70,7 @@ 6.4 // We intercept "new" on StaticClass instances to provide additional capabilities 6.5 if ("new".equals(desc.getNameToken(CallSiteDescriptor.OPERATOR))) { 6.6 // make sure new is on accessible Class 6.7 - Context.checkPackageAccess(receiverClass.getName()); 6.8 + Context.checkPackageAccess(receiverClass); 6.9 6.10 // Is the class abstract? (This includes interfaces.) 6.11 if (NashornLinker.isAbstractClass(receiverClass)) {
7.1 --- a/test/script/basic/JDK-8023026.js Tue Oct 01 14:38:56 2013 +0530 7.2 +++ b/test/script/basic/JDK-8023026.js Fri Oct 04 16:21:29 2013 +0530 7.3 @@ -48,7 +48,7 @@ 7.4 function(x) x*x)); 7.5 } 7.6 7.7 -var array = new (Java.type("[I"))(4); 7.8 +var array = new (Java.type("int[]"))(4); 7.9 for (var i in array) { 7.10 array[i] = i; 7.11 }
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 8.2 +++ b/test/script/sandbox/arrayclass.js Fri Oct 04 16:21:29 2013 +0530 8.3 @@ -0,0 +1,37 @@ 8.4 +/* 8.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 8.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 8.7 + * 8.8 + * This code is free software; you can redistribute it and/or modify it 8.9 + * under the terms of the GNU General Public License version 2 only, as 8.10 + * published by the Free Software Foundation. 8.11 + * 8.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 8.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 8.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 8.15 + * version 2 for more details (a copy is included in the LICENSE file that 8.16 + * accompanied this code). 8.17 + * 8.18 + * You should have received a copy of the GNU General Public License version 8.19 + * 2 along with this work; if not, write to the Free Software Foundation, 8.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 8.21 + * 8.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 8.23 + * or visit www.oracle.com if you need additional information or have any 8.24 + * questions. 8.25 + */ 8.26 + 8.27 +/** 8.28 + * Try to access array class of a sensitive class like Unsafe. 8.29 + * 8.30 + * @test 8.31 + * @security 8.32 + * @run 8.33 + */ 8.34 + 8.35 +try { 8.36 + var unsafeArr = Java.type("[Lsun.misc.Unsafe;"); 8.37 + fail("No Exception for [Lsun.misc.Unsafe;"); 8.38 +} catch (e) { 8.39 + print(e); 8.40 +}
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/test/script/sandbox/arrayclass.js.EXPECTED Fri Oct 04 16:21:29 2013 +0530 9.3 @@ -0,0 +1,1 @@ 9.4 +java.lang.ClassNotFoundException: [Lsun.misc.Unsafe;