8343982: Remove usage of security manager from ClassLoader and related classes

Reviewed-by: jpai, yzheng, lancea
This commit is contained in:
Alan Bateman 2024-11-15 07:16:34 +00:00
parent 99070658fd
commit 0ae5748f74
7 changed files with 78 additions and 433 deletions

View File

@ -64,7 +64,6 @@ import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.CallerSensitiveAdapter; import jdk.internal.reflect.CallerSensitiveAdapter;
import jdk.internal.reflect.Reflection; import jdk.internal.reflect.Reflection;
import jdk.internal.util.StaticProperty; import jdk.internal.util.StaticProperty;
import sun.security.util.SecurityConstants;
/** /**
* A class loader is an object that is responsible for loading classes. The * A class loader is an object that is responsible for loading classes. The
@ -357,12 +356,6 @@ public abstract class ClassLoader {
if (name != null && name.isEmpty()) { if (name != null && name.isEmpty()) {
throw new IllegalArgumentException("name must be non-empty or null"); throw new IllegalArgumentException("name must be non-empty or null");
} }
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkCreateClassLoader();
}
return null; return null;
} }
@ -1735,18 +1728,7 @@ public abstract class ClassLoader {
* *
* @since 1.2 * @since 1.2
*/ */
@CallerSensitive
public final ClassLoader getParent() { public final ClassLoader getParent() {
if (parent == null)
return null;
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Check access to the parent class loader
// If the caller's class loader is same as this class loader,
// permission check is performed.
checkClassLoaderPermission(parent, Reflection.getCallerClass());
}
return parent; return parent;
} }
@ -1774,15 +1756,8 @@ public abstract class ClassLoader {
* *
* @since 9 * @since 9
*/ */
@CallerSensitive
public static ClassLoader getPlatformClassLoader() { public static ClassLoader getPlatformClassLoader() {
@SuppressWarnings("removal") return getBuiltinPlatformClassLoader();
SecurityManager sm = System.getSecurityManager();
ClassLoader loader = getBuiltinPlatformClassLoader();
if (sm != null) {
checkClassLoaderPermission(loader, Reflection.getCallerClass());
}
return loader;
} }
/** /**
@ -1853,7 +1828,6 @@ public abstract class ClassLoader {
* underlying cause of the error can be retrieved via the * underlying cause of the error can be retrieved via the
* {@link Throwable#getCause()} method. * {@link Throwable#getCause()} method.
*/ */
@CallerSensitive
public static ClassLoader getSystemClassLoader() { public static ClassLoader getSystemClassLoader() {
switch (VM.initLevel()) { switch (VM.initLevel()) {
case 0: case 0:
@ -1867,11 +1841,6 @@ public abstract class ClassLoader {
default: default:
// system fully initialized // system fully initialized
assert VM.isBooted() && scl != null; assert VM.isBooted() && scl != null;
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkClassLoaderPermission(scl, Reflection.getCallerClass());
}
return scl; return scl;
} }
} }
@ -1902,8 +1871,6 @@ public abstract class ClassLoader {
} }
ClassLoader builtinLoader = getBuiltinAppClassLoader(); ClassLoader builtinLoader = getBuiltinAppClassLoader();
// All are privileged frames. No need to call doPrivileged.
String cn = System.getProperty("java.system.class.loader"); String cn = System.getProperty("java.system.class.loader");
if (cn != null) { if (cn != null) {
try { try {
@ -1930,36 +1897,6 @@ public abstract class ClassLoader {
return scl; return scl;
} }
// Returns true if the specified class loader can be found in this class
// loader's delegation chain.
boolean isAncestor(ClassLoader cl) {
ClassLoader acl = this;
do {
acl = acl.parent;
if (cl == acl) {
return true;
}
} while (acl != null);
return false;
}
// Tests if class loader access requires "getClassLoader" permission
// check. A class loader 'from' can access class loader 'to' if
// class loader 'from' is same as class loader 'to' or an ancestor
// of 'to'. The class loader in a system domain can access
// any class loader.
private static boolean needsClassLoaderPermissionCheck(ClassLoader from,
ClassLoader to)
{
if (from == to)
return false;
if (from == null)
return false;
return !to.isAncestor(from);
}
// Returns the class's class loader, or null if none. // Returns the class's class loader, or null if none.
static ClassLoader getClassLoader(Class<?> caller) { static ClassLoader getClassLoader(Class<?> caller) {
// This can be null if the VM is requesting it // This can be null if the VM is requesting it
@ -1970,23 +1907,6 @@ public abstract class ClassLoader {
return caller.getClassLoader0(); return caller.getClassLoader0();
} }
/*
* Checks RuntimePermission("getClassLoader") permission
* if caller's class loader is not null and caller's class loader
* is not the same as or an ancestor of the given cl argument.
*/
static void checkClassLoaderPermission(ClassLoader cl, Class<?> caller) {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// caller can be null if the VM is requesting it
ClassLoader ccl = getClassLoader(caller);
if (needsClassLoaderPermissionCheck(ccl, cl)) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
}
// The system class loader // The system class loader
// @GuardedBy("ClassLoader.class") // @GuardedBy("ClassLoader.class")
private static volatile ClassLoader scl; private static volatile ClassLoader scl;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -32,8 +32,6 @@ import java.net.URI;
import java.net.URL; import java.net.URL;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays; import java.util.Arrays;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -143,18 +141,8 @@ public class BootLoader {
/** /**
* Loads a native library from the system library path. * Loads a native library from the system library path.
*/ */
@SuppressWarnings("removal")
public static void loadLibrary(String name) { public static void loadLibrary(String name) {
if (System.getSecurityManager() == null) { getNativeLibraries().loadLibrary(name);
BootLoader.getNativeLibraries().loadLibrary(name);
} else {
AccessController.doPrivileged(new java.security.PrivilegedAction<>() {
public Void run() {
BootLoader.getNativeLibraries().loadLibrary(name);
return null;
}
});
}
} }
/** /**
@ -294,38 +282,28 @@ public class BootLoader {
/** /**
* Returns URL if the given location is a regular file path. * Returns URL if the given location is a regular file path.
*/ */
@SuppressWarnings("removal")
private static URL toFileURL(String location) { private static URL toFileURL(String location) {
return AccessController.doPrivileged(new PrivilegedAction<>() { Path path = Path.of(location);
public URL run() { if (Files.isRegularFile(path)) {
Path path = Path.of(location); try {
if (Files.isRegularFile(path)) { return path.toUri().toURL();
try { } catch (MalformedURLException e) {}
return path.toUri().toURL(); }
} catch (MalformedURLException e) {} return null;
}
return null;
}
});
} }
/** /**
* Returns the Manifest if the given location is a JAR file * Returns the Manifest if the given location is a JAR file
* containing a manifest. * containing a manifest.
*/ */
@SuppressWarnings("removal")
private static Manifest getManifest(String location) { private static Manifest getManifest(String location) {
return AccessController.doPrivileged(new PrivilegedAction<>() { Path jar = Path.of(location);
public Manifest run() { try (InputStream in = Files.newInputStream(jar);
Path jar = Path.of(location); JarInputStream jis = new JarInputStream(in, false)) {
try (InputStream in = Files.newInputStream(jar); return jis.getManifest();
JarInputStream jis = new JarInputStream(in, false)) { } catch (IOException e) {
return jis.getManifest(); return null;
} catch (IOException e) { }
return null;
}
}
});
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -35,13 +35,8 @@ import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.net.URL;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.security.AccessController;
import java.security.CodeSigner; import java.security.CodeSigner;
import java.security.CodeSource; import java.security.CodeSource;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.SecureClassLoader; import java.security.SecureClassLoader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -62,7 +57,6 @@ import jdk.internal.misc.VM;
import jdk.internal.module.ModulePatcher.PatchedModuleReader; import jdk.internal.module.ModulePatcher.PatchedModuleReader;
import jdk.internal.module.Resources; import jdk.internal.module.Resources;
import jdk.internal.vm.annotation.Stable; import jdk.internal.vm.annotation.Stable;
import sun.security.util.LazyCodeSourcePermissionCollection;
/** /**
@ -281,31 +275,30 @@ public class BuiltinClassLoader
url = findResourceOnClassPath(name); url = findResourceOnClassPath(name);
} }
return checkURL(url); // check access before returning return url;
} }
/** /**
* Returns an input stream to a resource of the given name in a module * Returns an input stream to a resource of the given name in a module
* defined to this class loader. * defined to this class loader.
*/ */
@SuppressWarnings("removal")
public InputStream findResourceAsStream(String mn, String name) public InputStream findResourceAsStream(String mn, String name)
throws IOException throws IOException
{ {
// Need URL to resource when running with a security manager so that InputStream in = null;
// the right permission check is done. if (mn != null) {
if (System.getSecurityManager() != null || mn == null) { // find in module defined to this loader
URL url = findResource(mn, name); ModuleReference mref = nameToModule.get(mn);
return (url != null) ? url.openStream() : null; if (mref != null) {
} in = moduleReaderFor(mref).open(name).orElse(null);
}
// find in module defined to this loader, no security manager
ModuleReference mref = nameToModule.get(mn);
if (mref != null) {
return moduleReaderFor(mref).open(name).orElse(null);
} else { } else {
return null; URL url = findResourceOnClassPath(name);
if (url != null) {
in = url.openStream();
}
} }
return in;
} }
/** /**
@ -342,7 +335,7 @@ public class BuiltinClassLoader
if (!urls.isEmpty()) { if (!urls.isEmpty()) {
URL url = urls.get(0); URL url = urls.get(0);
if (url != null) { if (url != null) {
return checkURL(url); // check access before returning return url;
} }
} }
} catch (IOException ioe) { } catch (IOException ioe) {
@ -352,8 +345,7 @@ public class BuiltinClassLoader
} }
// search class path // search class path
URL url = findResourceOnClassPath(name); return findResourceOnClassPath(name);
return checkURL(url);
} }
/** /**
@ -383,7 +375,6 @@ public class BuiltinClassLoader
} else { } else {
// not in a package of a module defined to this loader // not in a package of a module defined to this loader
for (URL url : findMiscResource(name)) { for (URL url : findMiscResource(name)) {
url = checkURL(url);
if (url != null) { if (url != null) {
checked.add(url); checked.add(url);
} }
@ -406,7 +397,7 @@ public class BuiltinClassLoader
} else { } else {
// need to check each URL // need to check each URL
while (e.hasMoreElements() && next == null) { while (e.hasMoreElements() && next == null) {
next = checkURL(e.nextElement()); next = e.nextElement();
} }
return next != null; return next != null;
} }
@ -436,7 +427,6 @@ public class BuiltinClassLoader
* *
* The cache used by this method avoids repeated searching of all modules. * The cache used by this method avoids repeated searching of all modules.
*/ */
@SuppressWarnings("removal")
private List<URL> findMiscResource(String name) throws IOException { private List<URL> findMiscResource(String name) throws IOException {
SoftReference<Map<String, List<URL>>> ref = this.resourceCache; SoftReference<Map<String, List<URL>>> ref = this.resourceCache;
Map<String, List<URL>> map = (ref != null) ? ref.get() : null; Map<String, List<URL>> map = (ref != null) ? ref.get() : null;
@ -453,30 +443,20 @@ public class BuiltinClassLoader
} }
// search all modules for the resource // search all modules for the resource
List<URL> urls; List<URL> urls = null;
try { for (ModuleReference mref : nameToModule.values()) {
urls = AccessController.doPrivileged( URI u = moduleReaderFor(mref).find(name).orElse(null);
new PrivilegedExceptionAction<>() { if (u != null) {
@Override try {
public List<URL> run() throws IOException { if (urls == null)
List<URL> result = null; urls = new ArrayList<>();
for (ModuleReference mref : nameToModule.values()) { urls.add(u.toURL());
URI u = moduleReaderFor(mref).find(name).orElse(null); } catch (MalformedURLException | IllegalArgumentException e) {
if (u != null) { }
try { }
if (result == null) }
result = new ArrayList<>(); if (urls == null) {
result.add(u.toURL()); urls = List.of();
} catch (MalformedURLException |
IllegalArgumentException e) {
}
}
}
return (result != null) ? result : Collections.emptyList();
}
});
} catch (PrivilegedActionException pae) {
throw (IOException) pae.getCause();
} }
// only cache resources after VM is fully initialized // only cache resources after VM is fully initialized
@ -490,23 +470,8 @@ public class BuiltinClassLoader
/** /**
* Returns the URL to a resource in a module or {@code null} if not found. * Returns the URL to a resource in a module or {@code null} if not found.
*/ */
@SuppressWarnings("removal")
private URL findResource(ModuleReference mref, String name) throws IOException { private URL findResource(ModuleReference mref, String name) throws IOException {
URI u; URI u = moduleReaderFor(mref).find(name).orElse(null);
if (System.getSecurityManager() == null) {
u = moduleReaderFor(mref).find(name).orElse(null);
} else {
try {
u = AccessController.doPrivileged(new PrivilegedExceptionAction<> () {
@Override
public URI run() throws IOException {
return moduleReaderFor(mref).find(name).orElse(null);
}
});
} catch (PrivilegedActionException pae) {
throw (IOException) pae.getCause();
}
}
if (u != null) { if (u != null) {
try { try {
return u.toURL(); return u.toURL();
@ -515,30 +480,12 @@ public class BuiltinClassLoader
return null; return null;
} }
/**
* Returns the URL to a resource in a module. Returns {@code null} if not found
* or an I/O error occurs.
*/
private URL findResourceOrNull(ModuleReference mref, String name) {
try {
return findResource(mref, name);
} catch (IOException ignore) {
return null;
}
}
/** /**
* Returns a URL to a resource on the class path. * Returns a URL to a resource on the class path.
*/ */
@SuppressWarnings("removal")
private URL findResourceOnClassPath(String name) { private URL findResourceOnClassPath(String name) {
if (hasClassPath()) { if (hasClassPath()) {
if (System.getSecurityManager() == null) { return ucp.findResource(name, false);
return ucp.findResource(name, false);
} else {
PrivilegedAction<URL> pa = () -> ucp.findResource(name, false);
return AccessController.doPrivileged(pa);
}
} else { } else {
// no class path // no class path
return null; return null;
@ -548,16 +495,9 @@ public class BuiltinClassLoader
/** /**
* Returns the URLs of all resources of the given name on the class path. * Returns the URLs of all resources of the given name on the class path.
*/ */
@SuppressWarnings("removal")
private Enumeration<URL> findResourcesOnClassPath(String name) { private Enumeration<URL> findResourcesOnClassPath(String name) {
if (hasClassPath()) { if (hasClassPath()) {
if (System.getSecurityManager() == null) { return ucp.findResources(name, false);
return ucp.findResources(name, false);
} else {
PrivilegedAction<Enumeration<URL>> pa;
pa = () -> ucp.findResources(name, false);
return AccessController.doPrivileged(pa);
}
} else { } else {
// no class path // no class path
return Collections.emptyEnumeration(); return Collections.emptyEnumeration();
@ -735,14 +675,8 @@ public class BuiltinClassLoader
* *
* @return the resulting Class or {@code null} if not found * @return the resulting Class or {@code null} if not found
*/ */
@SuppressWarnings("removal")
private Class<?> findClassInModuleOrNull(LoadedModule loadedModule, String cn) { private Class<?> findClassInModuleOrNull(LoadedModule loadedModule, String cn) {
if (System.getSecurityManager() == null) { return defineClass(cn, loadedModule);
return defineClass(cn, loadedModule);
} else {
PrivilegedAction<Class<?>> pa = () -> defineClass(cn, loadedModule);
return AccessController.doPrivileged(pa);
}
} }
/** /**
@ -750,36 +684,17 @@ public class BuiltinClassLoader
* *
* @return the resulting Class or {@code null} if not found * @return the resulting Class or {@code null} if not found
*/ */
@SuppressWarnings("removal")
private Class<?> findClassOnClassPathOrNull(String cn) { private Class<?> findClassOnClassPathOrNull(String cn) {
String path = cn.replace('.', '/').concat(".class"); String path = cn.replace('.', '/').concat(".class");
if (System.getSecurityManager() == null) { Resource res = ucp.getResource(path, false);
Resource res = ucp.getResource(path, false); if (res != null) {
if (res != null) { try {
try { return defineClass(cn, res);
return defineClass(cn, res); } catch (IOException ioe) {
} catch (IOException ioe) { // TBD on how I/O errors should be propagated
// TBD on how I/O errors should be propagated
}
} }
return null;
} else {
// avoid use of lambda here
PrivilegedAction<Class<?>> pa = new PrivilegedAction<>() {
public Class<?> run() {
Resource res = ucp.getResource(path, false);
if (res != null) {
try {
return defineClass(cn, res);
} catch (IOException ioe) {
// TBD on how I/O errors should be propagated
}
}
return null;
}
};
return AccessController.doPrivileged(pa);
} }
return null;
} }
/** /**
@ -998,16 +913,6 @@ public class BuiltinClassLoader
return "true".equalsIgnoreCase(sealed); return "true".equalsIgnoreCase(sealed);
} }
// -- permissions
/**
* Returns the permissions for the given CodeSource.
*/
@Override
protected PermissionCollection getPermissions(CodeSource cs) {
return new LazyCodeSourcePermissionCollection(super.getPermissions(cs), cs);
}
// -- miscellaneous supporting methods // -- miscellaneous supporting methods
/** /**
@ -1072,14 +977,6 @@ public class BuiltinClassLoader
return false; return false;
} }
/**
* Checks access to the given URL. We use URLClassPath for consistent
* checking with java.net.URLClassLoader.
*/
private static URL checkURL(URL url) {
return URLClassPath.checkURL(url);
}
// Called from VM only, during -Xshare:dump // Called from VM only, during -Xshare:dump
private void resetArchivedStates() { private void resetArchivedStates() {
ucp = null; ucp = null;

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,8 +29,6 @@ import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.nio.file.InvalidPathException; import java.nio.file.InvalidPathException;
import java.nio.file.Path; import java.nio.file.Path;
import java.security.CodeSource;
import java.security.PermissionCollection;
import java.util.jar.Manifest; import java.util.jar.Manifest;
import jdk.internal.access.JavaLangAccess; import jdk.internal.access.JavaLangAccess;
@ -170,31 +168,6 @@ public class ClassLoaders {
super("app", parent, ucp); super("app", parent, ucp);
} }
@Override
protected Class<?> loadClass(String cn, boolean resolve)
throws ClassNotFoundException
{
// for compatibility reasons, say where restricted package list has
// been updated to list API packages in the unnamed module.
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
int i = cn.lastIndexOf('.');
if (i != -1) {
sm.checkPackageAccess(cn.substring(0, i));
}
}
return super.loadClass(cn, resolve);
}
@Override
protected PermissionCollection getPermissions(CodeSource cs) {
PermissionCollection perms = super.getPermissions(cs);
perms.add(new RuntimePermission("exitVM"));
return perms;
}
/** /**
* Called by the VM to support dynamic additions to the class path * Called by the VM to support dynamic additions to the class path
* *
@ -207,6 +180,7 @@ public class ClassLoaders {
/** /**
* Called by the VM to support define package for AppCDS * Called by the VM to support define package for AppCDS
*/ */
@Override
protected Package defineOrCheckPackage(String pn, Manifest man, URL url) { protected Package defineOrCheckPackage(String pn, Manifest man, URL url) {
return super.defineOrCheckPackage(pn, man, url); return super.defineOrCheckPackage(pn, man, url);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -25,8 +25,6 @@
package jdk.internal.loader; package jdk.internal.loader;
import java.io.File;
import java.io.FilePermission;
import java.io.IOException; import java.io.IOException;
import java.lang.module.Configuration; import java.lang.module.Configuration;
import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleDescriptor;
@ -37,15 +35,8 @@ import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.net.URL;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.CodeSigner; import java.security.CodeSigner;
import java.security.CodeSource; import java.security.CodeSource;
import java.security.Permission;
import java.security.PermissionCollection;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.security.SecureClassLoader; import java.security.SecureClassLoader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
@ -110,16 +101,11 @@ public final class Loader extends SecureClassLoader {
private final Map<ModuleReference, ModuleReader> moduleToReader private final Map<ModuleReference, ModuleReader> moduleToReader
= new ConcurrentHashMap<>(); = new ConcurrentHashMap<>();
// ACC used when loading classes and resources
@SuppressWarnings("removal")
private final AccessControlContext acc;
/** /**
* A module defined/loaded to a {@code Loader}. * A module defined/loaded to a {@code Loader}.
*/ */
private static class LoadedModule { private static class LoadedModule {
private final ModuleReference mref; private final ModuleReference mref;
private final URL url; // may be null
private final CodeSource cs; private final CodeSource cs;
LoadedModule(ModuleReference mref) { LoadedModule(ModuleReference mref) {
@ -130,13 +116,11 @@ public final class Loader extends SecureClassLoader {
} catch (MalformedURLException | IllegalArgumentException e) { } } catch (MalformedURLException | IllegalArgumentException e) { }
} }
this.mref = mref; this.mref = mref;
this.url = url;
this.cs = new CodeSource(url, (CodeSigner[]) null); this.cs = new CodeSource(url, (CodeSigner[]) null);
} }
ModuleReference mref() { return mref; } ModuleReference mref() { return mref; }
String name() { return mref.descriptor().name(); } String name() { return mref.descriptor().name(); }
URL location() { return url; }
CodeSource codeSource() { return cs; } CodeSource codeSource() { return cs; }
} }
@ -145,7 +129,6 @@ public final class Loader extends SecureClassLoader {
* Creates a {@code Loader} in a loader pool that loads classes/resources * Creates a {@code Loader} in a loader pool that loads classes/resources
* from one module. * from one module.
*/ */
@SuppressWarnings("removal")
public Loader(ResolvedModule resolvedModule, public Loader(ResolvedModule resolvedModule,
LoaderPool pool, LoaderPool pool,
ClassLoader parent) ClassLoader parent)
@ -164,8 +147,6 @@ public final class Loader extends SecureClassLoader {
LoadedModule lm = new LoadedModule(mref); LoadedModule lm = new LoadedModule(mref);
descriptor.packages().forEach(pn -> localPackageToModule.put(pn, lm)); descriptor.packages().forEach(pn -> localPackageToModule.put(pn, lm));
this.localPackageToModule = localPackageToModule; this.localPackageToModule = localPackageToModule;
this.acc = AccessController.getContext();
} }
/** /**
@ -175,7 +156,6 @@ public final class Loader extends SecureClassLoader {
* @throws IllegalArgumentException * @throws IllegalArgumentException
* If two or more modules have the same package * If two or more modules have the same package
*/ */
@SuppressWarnings("removal")
public Loader(Collection<ResolvedModule> modules, ClassLoader parent) { public Loader(Collection<ResolvedModule> modules, ClassLoader parent) {
super(parent); super(parent);
@ -197,8 +177,6 @@ public final class Loader extends SecureClassLoader {
} }
this.nameToModule = nameToModule; this.nameToModule = nameToModule;
this.localPackageToModule = localPackageToModule; this.localPackageToModule = localPackageToModule;
this.acc = AccessController.getContext();
} }
/** /**
@ -326,7 +304,6 @@ public final class Loader extends SecureClassLoader {
* Returns a URL to a resource of the given name in a module defined to * Returns a URL to a resource of the given name in a module defined to
* this class loader. * this class loader.
*/ */
@SuppressWarnings("removal")
@Override @Override
protected URL findResource(String mn, String name) throws IOException { protected URL findResource(String mn, String name) throws IOException {
ModuleReference mref = (mn != null) ? nameToModule.get(mn) : null; ModuleReference mref = (mn != null) ? nameToModule.get(mn) : null;
@ -335,41 +312,12 @@ public final class Loader extends SecureClassLoader {
// locate resource // locate resource
URL url = null; URL url = null;
try { Optional<URI> ouri = moduleReaderFor(mref).find(name);
url = AccessController.doPrivileged( if (ouri.isPresent()) {
new PrivilegedExceptionAction<URL>() {
@Override
public URL run() throws IOException {
Optional<URI> ouri = moduleReaderFor(mref).find(name);
if (ouri.isPresent()) {
try {
return ouri.get().toURL();
} catch (MalformedURLException |
IllegalArgumentException e) { }
}
return null;
}
});
} catch (PrivilegedActionException pae) {
throw (IOException) pae.getCause();
}
// check access with permissions restricted by ACC
if (url != null && System.getSecurityManager() != null) {
try { try {
URL urlToCheck = url; url = ouri.get().toURL();
url = AccessController.doPrivileged( } catch (MalformedURLException | IllegalArgumentException e) { }
new PrivilegedExceptionAction<URL>() {
@Override
public URL run() throws IOException {
return URLClassPath.checkURL(urlToCheck);
}
}, acc);
} catch (PrivilegedActionException pae) {
url = null;
}
} }
return url; return url;
} }
@ -525,15 +473,6 @@ public final class Loader extends SecureClassLoader {
protected Class<?> loadClass(String cn, boolean resolve) protected Class<?> loadClass(String cn, boolean resolve)
throws ClassNotFoundException throws ClassNotFoundException
{ {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
String pn = packageName(cn);
if (!pn.isEmpty()) {
sm.checkPackageAccess(pn);
}
}
synchronized (getClassLoadingLock(cn)) { synchronized (getClassLoadingLock(cn)) {
// check if already loaded // check if already loaded
Class<?> c = findLoadedClass(cn); Class<?> c = findLoadedClass(cn);
@ -584,19 +523,7 @@ public final class Loader extends SecureClassLoader {
* *
* @return the resulting Class or {@code null} if not found * @return the resulting Class or {@code null} if not found
*/ */
@SuppressWarnings("removal")
private Class<?> findClassInModuleOrNull(LoadedModule loadedModule, String cn) { private Class<?> findClassInModuleOrNull(LoadedModule loadedModule, String cn) {
PrivilegedAction<Class<?>> pa = () -> defineClass(cn, loadedModule);
return AccessController.doPrivileged(pa, acc);
}
/**
* Defines the given binary class name to the VM, loading the class
* bytes from the given module.
*
* @return the resulting Class or {@code null} if an I/O error occurs
*/
private Class<?> defineClass(String cn, LoadedModule loadedModule) {
ModuleReader reader = moduleReaderFor(loadedModule.mref()); ModuleReader reader = moduleReaderFor(loadedModule.mref());
try { try {
@ -620,40 +547,6 @@ public final class Loader extends SecureClassLoader {
} }
} }
// -- permissions
/**
* Returns the permissions for the given CodeSource.
*/
@Override
protected PermissionCollection getPermissions(CodeSource cs) {
PermissionCollection perms = super.getPermissions(cs);
URL url = cs.getLocation();
if (url == null)
return perms;
// add the permission to access the resource
try {
Permission p = url.openConnection().getPermission();
if (p != null) {
// for directories then need recursive access
if (p instanceof FilePermission) {
String path = p.getName();
if (path.endsWith(File.separator)) {
path += "-";
p = new FilePermission(path, "read");
}
}
perms.add(p);
}
} catch (IOException ioe) { }
return perms;
}
// -- miscellaneous supporting methods // -- miscellaneous supporting methods
/** /**

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -114,25 +114,17 @@ public final class NativeLibraries {
* @param file the path of the native library * @param file the path of the native library
* @throws UnsatisfiedLinkError if any error in loading the native library * @throws UnsatisfiedLinkError if any error in loading the native library
*/ */
@SuppressWarnings("removal")
public NativeLibrary loadLibrary(Class<?> fromClass, File file) { public NativeLibrary loadLibrary(Class<?> fromClass, File file) {
// Check to see if we're attempting to access a static library // Check to see if we're attempting to access a static library
String name = findBuiltinLib(file.getName()); String name = findBuiltinLib(file.getName());
boolean isBuiltin = (name != null); boolean isBuiltin = (name != null);
if (!isBuiltin) { if (!isBuiltin) {
name = AccessController.doPrivileged(new PrivilegedAction<>() { try {
public String run() { if (loadLibraryOnlyIfPresent && !file.exists()) {
try { return null;
if (loadLibraryOnlyIfPresent && !file.exists()) { }
return null; name = file.getCanonicalPath();
} } catch (IOException e) {
return file.getCanonicalPath();
} catch (IOException e) {
return null;
}
}
});
if (name == null) {
return null; return null;
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -29,8 +29,6 @@ import jdk.internal.misc.VM;
import java.io.IOException; import java.io.IOException;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.nio.file.Path; import java.nio.file.Path;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -78,18 +76,11 @@ public final class RawNativeLibraries {
* *
* @param path the path of the native library * @param path the path of the native library
*/ */
@SuppressWarnings("removal")
public NativeLibrary load(Path path) { public NativeLibrary load(Path path) {
String name = AccessController.doPrivileged(new PrivilegedAction<>() { String name;
public String run() { try {
try { name = path.toRealPath().toString();
return path.toRealPath().toString(); } catch (IOException e) {
} catch (IOException e) {
return null;
}
}
});
if (name == null) {
return null; return null;
} }
return load(name); return load(name);