--- a/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Wed Jul 27 02:23:16 2016 +0000
+++ b/jdk/src/java.base/share/classes/java/net/URLClassLoader.java Thu Jul 28 10:13:12 2016 +0100
@@ -115,8 +115,8 @@
if (security != null) {
security.checkCreateClassLoader();
}
- this.ucp = new URLClassPath(urls);
this.acc = AccessController.getContext();
+ this.ucp = new URLClassPath(urls, acc);
}
URLClassLoader(String name, URL[] urls, ClassLoader parent,
@@ -127,8 +127,8 @@
if (security != null) {
security.checkCreateClassLoader();
}
- this.ucp = new URLClassPath(urls);
this.acc = acc;
+ this.ucp = new URLClassPath(urls, acc);
}
/**
@@ -159,8 +159,8 @@
if (security != null) {
security.checkCreateClassLoader();
}
- this.ucp = new URLClassPath(urls);
this.acc = AccessController.getContext();
+ this.ucp = new URLClassPath(urls, acc);
}
URLClassLoader(URL[] urls, AccessControlContext acc) {
@@ -170,8 +170,8 @@
if (security != null) {
security.checkCreateClassLoader();
}
- this.ucp = new URLClassPath(urls);
this.acc = acc;
+ this.ucp = new URLClassPath(urls, acc);
}
/**
@@ -203,8 +203,8 @@
if (security != null) {
security.checkCreateClassLoader();
}
- this.ucp = new URLClassPath(urls, factory);
this.acc = AccessController.getContext();
+ this.ucp = new URLClassPath(urls, factory, acc);
}
@@ -238,8 +238,8 @@
if (security != null) {
security.checkCreateClassLoader();
}
- this.ucp = new URLClassPath(urls);
this.acc = AccessController.getContext();
+ this.ucp = new URLClassPath(urls, acc);
}
/**
@@ -271,8 +271,8 @@
if (security != null) {
security.checkCreateClassLoader();
}
- this.ucp = new URLClassPath(urls, factory);
this.acc = AccessController.getContext();
+ this.ucp = new URLClassPath(urls, factory, acc);
}
/* A map (used as a set) to keep track of closeable local resources
--- a/jdk/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java Wed Jul 27 02:23:16 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java Thu Jul 28 10:13:12 2016 +0100
@@ -38,6 +38,7 @@
import java.net.URLConnection;
import java.net.URLStreamHandler;
import java.net.URLStreamHandlerFactory;
+import java.security.AccessControlContext;
import java.security.AccessControlException;
import java.security.AccessController;
import java.security.CodeSigner;
@@ -83,6 +84,7 @@
private static final String JAVA_VERSION;
private static final boolean DEBUG;
private static final boolean DISABLE_JAR_CHECKING;
+ private static final boolean DISABLE_ACC_CHECKING;
static {
Properties props = GetPropertyAction.privilegedGetProperties();
@@ -90,6 +92,9 @@
DEBUG = (props.getProperty("sun.misc.URLClassPath.debug") != null);
String p = props.getProperty("sun.misc.URLClassPath.disableJarChecking");
DISABLE_JAR_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
+
+ p = props.getProperty("jdk.net.URLClassPath.disableRestrictedPermissions");
+ DISABLE_ACC_CHECKING = p != null ? p.equals("true") || p.equals("") : false;
}
/* The original search path of URLs. */
@@ -110,6 +115,11 @@
/* Whether this URLClassLoader has been closed yet */
private boolean closed = false;
+ /* The context to be used when loading classes and resources. If non-null
+ * this is the context that was captured during the creation of the
+ * URLClassLoader. null implies no additional security restrictions. */
+ private final AccessControlContext acc;
+
/**
* Creates a new URLClassPath for the given URLs. The URLs will be
* searched in the order specified for classes and resources. A URL
@@ -119,8 +129,12 @@
* @param urls the directory and JAR file URLs to search for classes
* and resources
* @param factory the URLStreamHandlerFactory to use when creating new URLs
+ * @param acc the context to be used when loading classes and resources, may
+ * be null
*/
- public URLClassPath(URL[] urls, URLStreamHandlerFactory factory) {
+ public URLClassPath(URL[] urls,
+ URLStreamHandlerFactory factory,
+ AccessControlContext acc) {
for (int i = 0; i < urls.length; i++) {
path.add(urls[i]);
}
@@ -128,10 +142,22 @@
if (factory != null) {
jarHandler = factory.createURLStreamHandler("jar");
}
+ if (DISABLE_ACC_CHECKING)
+ this.acc = null;
+ else
+ this.acc = acc;
}
+ /**
+ * Constructs a URLClassPath with no additional security restrictions.
+ * Used by code that implements the class path.
+ */
public URLClassPath(URL[] urls) {
- this(urls, null);
+ this(urls, null, null);
+ }
+
+ public URLClassPath(URL[] urls, AccessControlContext acc) {
+ this(urls, null, acc);
}
public synchronized List<IOException> closeLoaders() {
@@ -356,6 +382,14 @@
} catch (IOException e) {
// Silently ignore for now...
continue;
+ } catch (SecurityException se) {
+ // Always silently ignore. The context, if there is one, that
+ // this URLClassPath was given during construction will never
+ // have permission to access the URL.
+ if (DEBUG) {
+ System.err.println("Failed to access " + url + ", " + se );
+ }
+ continue;
}
// Finally, add the Loader to the search path.
loaders.add(loader);
@@ -378,7 +412,7 @@
&& file != null && (file.indexOf("!/") == file.length() - 2)) {
// extract the nested URL
URL nestedUrl = new URL(file.substring(0, file.length() - 2));
- return new JarLoader(nestedUrl, jarHandler, lmap);
+ return new JarLoader(nestedUrl, jarHandler, lmap, acc);
} else if (file != null && file.endsWith("/")) {
if ("file".equals(protocol)) {
return new FileLoader(url);
@@ -386,10 +420,10 @@
return new Loader(url);
}
} else {
- return new JarLoader(url, jarHandler, lmap);
+ return new JarLoader(url, jarHandler, lmap, acc);
}
}
- });
+ }, acc);
} catch (java.security.PrivilegedActionException pae) {
throw (IOException)pae.getException();
}
@@ -585,10 +619,11 @@
*/
static class JarLoader extends Loader {
private JarFile jar;
- private URL csu;
+ private final URL csu;
private JarIndex index;
private URLStreamHandler handler;
- private HashMap<String, Loader> lmap;
+ private final HashMap<String, Loader> lmap;
+ private final AccessControlContext acc;
private boolean closed = false;
private static final JavaUtilZipFileAccess zipAccess =
SharedSecrets.getJavaUtilZipFileAccess();
@@ -598,13 +633,15 @@
* a JAR file.
*/
JarLoader(URL url, URLStreamHandler jarHandler,
- HashMap<String, Loader> loaderMap)
+ HashMap<String, Loader> loaderMap,
+ AccessControlContext acc)
throws IOException
{
super(new URL("jar", "", -1, url + "!/", jarHandler));
csu = url;
handler = jarHandler;
lmap = loaderMap;
+ this.acc = acc;
ensureOpen();
}
@@ -663,8 +700,7 @@
}
return null;
}
- }
- );
+ }, acc);
} catch (java.security.PrivilegedActionException pae) {
throw (IOException)pae.getException();
}
@@ -859,9 +895,9 @@
new PrivilegedExceptionAction<>() {
public JarLoader run() throws IOException {
return new JarLoader(url, handler,
- lmap);
+ lmap, acc);
}
- });
+ }, acc);
/* this newly opened jar file has its own index,
* merge it into the parent's index, taking into
--- a/jdk/src/java.base/share/classes/jdk/internal/util/jar/JarIndex.java Wed Jul 27 02:23:16 2016 +0000
+++ b/jdk/src/java.base/share/classes/jdk/internal/util/jar/JarIndex.java Thu Jul 28 10:13:12 2016 +0100
@@ -29,6 +29,7 @@
import java.util.*;
import java.util.jar.*;
import java.util.zip.*;
+import static sun.security.action.GetPropertyAction.privilegedGetProperty;
/**
* This class is used to maintain mappings from packages, classes
@@ -72,7 +73,7 @@
* be added to the index. Otherwise, just the directory names are added.
*/
private static final boolean metaInfFilenames =
- "true".equals(System.getProperty("sun.misc.JarIndex.metaInfFilenames"));
+ "true".equals(privilegedGetProperty("sun.misc.JarIndex.metaInfFilenames"));
/**
* Constructs a new, empty jar index.