8344011: Remove usage of security manager from Class and reflective APIs

Reviewed-by: liach, yzheng, rriggs
This commit is contained in:
Alan Bateman 2024-11-14 07:39:28 +00:00
parent c977ef7b45
commit abacece826
26 changed files with 163 additions and 1251 deletions

View File

@ -30,7 +30,6 @@ import java.lang.constant.ClassDesc;
import java.lang.constant.ConstantDescs; import java.lang.constant.ConstantDescs;
import java.lang.invoke.TypeDescriptor; import java.lang.invoke.TypeDescriptor;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.module.ModuleReader;
import java.lang.ref.SoftReference; import java.lang.ref.SoftReference;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -54,9 +53,7 @@ import java.lang.reflect.Type;
import java.lang.reflect.TypeVariable; import java.lang.reflect.TypeVariable;
import java.lang.constant.Constable; import java.lang.constant.Constable;
import java.net.URL; import java.net.URL;
import java.security.AccessController;
import java.security.Permissions; import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain; import java.security.ProtectionDomain;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -73,10 +70,8 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jdk.internal.constant.ConstantUtils; import jdk.internal.constant.ConstantUtils;
import jdk.internal.javac.PreviewFeature;
import jdk.internal.loader.BootLoader; import jdk.internal.loader.BootLoader;
import jdk.internal.loader.BuiltinClassLoader; import jdk.internal.loader.BuiltinClassLoader;
import jdk.internal.misc.PreviewFeatures;
import jdk.internal.misc.Unsafe; import jdk.internal.misc.Unsafe;
import jdk.internal.module.Resources; import jdk.internal.module.Resources;
import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.CallerSensitive;
@ -84,7 +79,6 @@ import jdk.internal.reflect.CallerSensitiveAdapter;
import jdk.internal.reflect.ConstantPool; import jdk.internal.reflect.ConstantPool;
import jdk.internal.reflect.Reflection; import jdk.internal.reflect.Reflection;
import jdk.internal.reflect.ReflectionFactory; import jdk.internal.reflect.ReflectionFactory;
import jdk.internal.vm.annotation.ForceInline;
import jdk.internal.vm.annotation.IntrinsicCandidate; import jdk.internal.vm.annotation.IntrinsicCandidate;
import jdk.internal.vm.annotation.Stable; import jdk.internal.vm.annotation.Stable;
@ -540,41 +534,10 @@ public final class Class<T> implements java.io.Serializable,
* @jls 13.1 The Form of a Binary * @jls 13.1 The Form of a Binary
* @since 1.2 * @since 1.2
*/ */
@CallerSensitive public static Class<?> forName(String name, boolean initialize, ClassLoader loader)
public static Class<?> forName(String name, boolean initialize,
ClassLoader loader)
throws ClassNotFoundException throws ClassNotFoundException
{ {
Class<?> caller = null; return forName0(name, initialize, loader, null);
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Reflective call to get caller class is only needed if a security manager
// is present. Avoid the overhead of making this call otherwise.
caller = Reflection.getCallerClass();
}
return forName(name, initialize, loader, caller);
}
// Caller-sensitive adapter method for reflective invocation
@CallerSensitiveAdapter
private static Class<?> forName(String name, boolean initialize, ClassLoader loader, Class<?> caller)
throws ClassNotFoundException
{
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// Reflective call to get caller class is only needed if a security manager
// is present. Avoid the overhead of making this call otherwise.
if (loader == null) {
ClassLoader ccl = ClassLoader.getClassLoader(caller);
if (ccl != null) {
sm.checkPermission(
SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
}
return forName0(name, initialize, loader, caller);
} }
/** Called after security check for system loader access checks have been made. */ /** Called after security check for system loader access checks have been made. */
@ -620,38 +583,11 @@ public final class Class<T> implements java.io.Serializable,
* @jls 12.3 Linking of Classes and Interfaces * @jls 12.3 Linking of Classes and Interfaces
* @since 9 * @since 9
*/ */
@SuppressWarnings("removal")
@CallerSensitive
public static Class<?> forName(Module module, String name) { public static Class<?> forName(Module module, String name) {
Class<?> caller = null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
caller = Reflection.getCallerClass();
}
return forName(module, name, caller);
}
// Caller-sensitive adapter method for reflective invocation
@SuppressWarnings("removal")
@CallerSensitiveAdapter
private static Class<?> forName(Module module, String name, Class<?> caller) {
Objects.requireNonNull(module); Objects.requireNonNull(module);
Objects.requireNonNull(name); Objects.requireNonNull(name);
ClassLoader cl; ClassLoader cl = module.getClassLoader();
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (caller != null && caller.getModule() != module) {
// if caller is null, Class.forName is the last java frame on the stack.
// java.base has all permissions
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
PrivilegedAction<ClassLoader> pa = module::getClassLoader;
cl = AccessController.doPrivileged(pa);
} else {
cl = module.getClassLoader();
}
if (cl != null) { if (cl != null) {
return cl.loadClass(module, name); return cl.loadClass(module, name);
} else { } else {
@ -740,17 +676,11 @@ public final class Class<T> implements java.io.Serializable,
* @throws ExceptionInInitializerError if the initialization * @throws ExceptionInInitializerError if the initialization
* provoked by this method fails. * provoked by this method fails.
*/ */
@SuppressWarnings("removal")
@CallerSensitive @CallerSensitive
@Deprecated(since="9") @Deprecated(since="9")
public T newInstance() public T newInstance()
throws InstantiationException, IllegalAccessException throws InstantiationException, IllegalAccessException
{ {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), false);
}
// Constructor lookup // Constructor lookup
Constructor<T> tmpConstructor = cachedConstructor; Constructor<T> tmpConstructor = cachedConstructor;
if (tmpConstructor == null) { if (tmpConstructor == null) {
@ -765,13 +695,7 @@ public final class Class<T> implements java.io.Serializable,
getConstructor0(empty, Member.DECLARED)); getConstructor0(empty, Member.DECLARED));
// Disable accessibility checks on the constructor // Disable accessibility checks on the constructor
// access check is done with the true caller // access check is done with the true caller
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<>() {
public Void run() {
c.setAccessible(true); c.setAccessible(true);
return null;
}
});
cachedConstructor = tmpConstructor = c; cachedConstructor = tmpConstructor = c;
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
throw (InstantiationException) throw (InstantiationException)
@ -1035,18 +959,8 @@ public final class Class<T> implements java.io.Serializable,
* represented by this {@code Class} object. * represented by this {@code Class} object.
* @see java.lang.ClassLoader * @see java.lang.ClassLoader
*/ */
@CallerSensitive
@ForceInline // to ensure Reflection.getCallerClass optimization
public ClassLoader getClassLoader() { public ClassLoader getClassLoader() {
ClassLoader cl = classLoader; return classLoader;
if (cl == null)
return null;
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader.checkClassLoaderPermission(cl, Reflection.getCallerClass());
}
return cl;
} }
// Package-private to allow ClassLoader access // Package-private to allow ClassLoader access
@ -1511,7 +1425,6 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since 1.5 * @since 1.5
*/ */
@CallerSensitive
public Method getEnclosingMethod() { public Method getEnclosingMethod() {
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo(); EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
@ -1533,14 +1446,7 @@ public final class Class<T> implements java.io.Serializable,
for(int i = 0; i < parameterClasses.length; i++) for(int i = 0; i < parameterClasses.length; i++)
parameterClasses[i] = toClass(parameterTypes[i]); parameterClasses[i] = toClass(parameterTypes[i]);
// Perform access check
final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass(); final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
enclosingCandidate.checkMemberAccess(sm, Member.DECLARED,
Reflection.getCallerClass(), true);
}
Method[] candidates = enclosingCandidate.privateGetDeclaredMethods(false); Method[] candidates = enclosingCandidate.privateGetDeclaredMethods(false);
/* /*
@ -1648,7 +1554,6 @@ public final class Class<T> implements java.io.Serializable,
* *
* @since 1.5 * @since 1.5
*/ */
@CallerSensitive
public Constructor<?> getEnclosingConstructor() { public Constructor<?> getEnclosingConstructor() {
EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo(); EnclosingMethodInfo enclosingInfo = getEnclosingMethodInfo();
@ -1669,15 +1574,8 @@ public final class Class<T> implements java.io.Serializable,
for (int i = 0; i < parameterClasses.length; i++) for (int i = 0; i < parameterClasses.length; i++)
parameterClasses[i] = toClass(parameterTypes[i]); parameterClasses[i] = toClass(parameterTypes[i]);
// Perform access check
final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
enclosingCandidate.checkMemberAccess(sm, Member.DECLARED,
Reflection.getCallerClass(), true);
}
final Class<?> enclosingCandidate = enclosingInfo.getEnclosingClass();
Constructor<?>[] candidates = enclosingCandidate Constructor<?>[] candidates = enclosingCandidate
.privateGetDeclaredConstructors(false); .privateGetDeclaredConstructors(false);
/* /*
@ -1708,19 +1606,8 @@ public final class Class<T> implements java.io.Serializable,
* @return the declaring class for this class * @return the declaring class for this class
* @since 1.1 * @since 1.1
*/ */
@CallerSensitive
public Class<?> getDeclaringClass() { public Class<?> getDeclaringClass() {
final Class<?> candidate = getDeclaringClass0(); return getDeclaringClass0();
if (candidate != null) {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
candidate.checkPackageAccess(sm,
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
}
}
return candidate;
} }
private native Class<?> getDeclaringClass0(); private native Class<?> getDeclaringClass0();
@ -1733,7 +1620,6 @@ public final class Class<T> implements java.io.Serializable,
* @return the immediately enclosing class of the underlying class * @return the immediately enclosing class of the underlying class
* @since 1.5 * @since 1.5
*/ */
@CallerSensitive
public Class<?> getEnclosingClass() { public Class<?> getEnclosingClass() {
// There are five kinds of classes (or interfaces): // There are five kinds of classes (or interfaces):
// a) Top level classes // a) Top level classes
@ -1760,15 +1646,6 @@ public final class Class<T> implements java.io.Serializable,
else else
enclosingCandidate = enclosingClass; enclosingCandidate = enclosingClass;
} }
if (enclosingCandidate != null) {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
enclosingCandidate.checkPackageAccess(sm,
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
}
}
return enclosingCandidate; return enclosingCandidate;
} }
@ -1991,23 +1868,7 @@ public final class Class<T> implements java.io.Serializable,
* members of this class * members of this class
* @since 1.1 * @since 1.1
*/ */
@SuppressWarnings("removal")
@CallerSensitive
public Class<?>[] getClasses() { public Class<?>[] getClasses() {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), false);
}
// Privileged so this implementation can look at DECLARED classes,
// something the caller might not have privilege to do. The code here
// is allowed to look at DECLARED classes because (1) it does not hand
// out anything other than public members and (2) public member access
// has already been ok'd by the SecurityManager.
return java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<>() {
public Class<?>[] run() {
List<Class<?>> list = new ArrayList<>(); List<Class<?>> list = new ArrayList<>();
Class<?> currentClass = Class.this; Class<?> currentClass = Class.this;
while (currentClass != null) { while (currentClass != null) {
@ -2020,8 +1881,6 @@ public final class Class<T> implements java.io.Serializable,
} }
return list.toArray(new Class<?>[0]); return list.toArray(new Class<?>[0]);
} }
});
}
/** /**
@ -2054,13 +1913,7 @@ public final class Class<T> implements java.io.Serializable,
* @jls 8.2 Class Members * @jls 8.2 Class Members
* @jls 8.3 Field Declarations * @jls 8.3 Field Declarations
*/ */
@CallerSensitive
public Field[] getFields() { public Field[] getFields() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
}
return copyFields(privateGetPublicFields()); return copyFields(privateGetPublicFields());
} }
@ -2138,13 +1991,7 @@ public final class Class<T> implements java.io.Serializable,
* @jls 8.4 Method Declarations * @jls 8.4 Method Declarations
* @since 1.1 * @since 1.1
*/ */
@CallerSensitive
public Method[] getMethods() { public Method[] getMethods() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
}
return copyMethods(privateGetPublicMethods()); return copyMethods(privateGetPublicMethods());
} }
@ -2173,13 +2020,7 @@ public final class Class<T> implements java.io.Serializable,
* @see #getDeclaredConstructors() * @see #getDeclaredConstructors()
* @since 1.1 * @since 1.1
*/ */
@CallerSensitive
public Constructor<?>[] getConstructors() { public Constructor<?>[] getConstructors() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
}
return copyConstructors(privateGetDeclaredConstructors(true)); return copyConstructors(privateGetDeclaredConstructors(true));
} }
@ -2219,14 +2060,8 @@ public final class Class<T> implements java.io.Serializable,
* @jls 8.2 Class Members * @jls 8.2 Class Members
* @jls 8.3 Field Declarations * @jls 8.3 Field Declarations
*/ */
@CallerSensitive
public Field getField(String name) throws NoSuchFieldException { public Field getField(String name) throws NoSuchFieldException {
Objects.requireNonNull(name); Objects.requireNonNull(name);
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
}
Field field = getField0(name); Field field = getField0(name);
if (field == null) { if (field == null) {
throw new NoSuchFieldException(name); throw new NoSuchFieldException(name);
@ -2322,15 +2157,9 @@ public final class Class<T> implements java.io.Serializable,
* @jls 8.4 Method Declarations * @jls 8.4 Method Declarations
* @since 1.1 * @since 1.1
*/ */
@CallerSensitive
public Method getMethod(String name, Class<?>... parameterTypes) public Method getMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException { throws NoSuchMethodException {
Objects.requireNonNull(name); Objects.requireNonNull(name);
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
}
Method method = getMethod0(name, parameterTypes); Method method = getMethod0(name, parameterTypes);
if (method == null) { if (method == null) {
throw new NoSuchMethodException(methodToString(name, parameterTypes)); throw new NoSuchMethodException(methodToString(name, parameterTypes));
@ -2363,14 +2192,8 @@ public final class Class<T> implements java.io.Serializable,
* @see #getDeclaredConstructor(Class[]) * @see #getDeclaredConstructor(Class[])
* @since 1.1 * @since 1.1
*/ */
@CallerSensitive
public Constructor<T> getConstructor(Class<?>... parameterTypes) public Constructor<T> getConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException { throws NoSuchMethodException {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
}
return getReflectionFactory().copyConstructor( return getReflectionFactory().copyConstructor(
getConstructor0(parameterTypes, Member.PUBLIC)); getConstructor0(parameterTypes, Member.PUBLIC));
} }
@ -2392,13 +2215,7 @@ public final class Class<T> implements java.io.Serializable,
* @since 1.1 * @since 1.1
* @jls 8.5 Member Class and Interface Declarations * @jls 8.5 Member Class and Interface Declarations
*/ */
@CallerSensitive
public Class<?>[] getDeclaredClasses() { public Class<?>[] getDeclaredClasses() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), false);
}
return getDeclaredClasses0(); return getDeclaredClasses0();
} }
@ -2425,13 +2242,7 @@ public final class Class<T> implements java.io.Serializable,
* @jls 8.2 Class Members * @jls 8.2 Class Members
* @jls 8.3 Field Declarations * @jls 8.3 Field Declarations
*/ */
@CallerSensitive
public Field[] getDeclaredFields() { public Field[] getDeclaredFields() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
}
return copyFields(privateGetDeclaredFields(false)); return copyFields(privateGetDeclaredFields(false));
} }
@ -2467,13 +2278,7 @@ public final class Class<T> implements java.io.Serializable,
* @jls 8.10 Record Classes * @jls 8.10 Record Classes
* @since 16 * @since 16
*/ */
@CallerSensitive
public RecordComponent[] getRecordComponents() { public RecordComponent[] getRecordComponents() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
}
if (!isRecord()) { if (!isRecord()) {
return null; return null;
} }
@ -2519,13 +2324,7 @@ public final class Class<T> implements java.io.Serializable,
* programming language and JVM modeling in core reflection</a> * programming language and JVM modeling in core reflection</a>
* @since 1.1 * @since 1.1
*/ */
@CallerSensitive
public Method[] getDeclaredMethods() { public Method[] getDeclaredMethods() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
}
return copyMethods(privateGetDeclaredMethods(false)); return copyMethods(privateGetDeclaredMethods(false));
} }
@ -2550,13 +2349,7 @@ public final class Class<T> implements java.io.Serializable,
* @see #getConstructors() * @see #getConstructors()
* @jls 8.8 Constructor Declarations * @jls 8.8 Constructor Declarations
*/ */
@CallerSensitive
public Constructor<?>[] getDeclaredConstructors() { public Constructor<?>[] getDeclaredConstructors() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
}
return copyConstructors(privateGetDeclaredConstructors(false)); return copyConstructors(privateGetDeclaredConstructors(false));
} }
@ -2581,14 +2374,8 @@ public final class Class<T> implements java.io.Serializable,
* @jls 8.2 Class Members * @jls 8.2 Class Members
* @jls 8.3 Field Declarations * @jls 8.3 Field Declarations
*/ */
@CallerSensitive
public Field getDeclaredField(String name) throws NoSuchFieldException { public Field getDeclaredField(String name) throws NoSuchFieldException {
Objects.requireNonNull(name); Objects.requireNonNull(name);
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
}
Field field = searchFields(privateGetDeclaredFields(false), name); Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) { if (field == null) {
throw new NoSuchFieldException(name); throw new NoSuchFieldException(name);
@ -2626,15 +2413,9 @@ public final class Class<T> implements java.io.Serializable,
* @jls 8.4 Method Declarations * @jls 8.4 Method Declarations
* @since 1.1 * @since 1.1
*/ */
@CallerSensitive
public Method getDeclaredMethod(String name, Class<?>... parameterTypes) public Method getDeclaredMethod(String name, Class<?>... parameterTypes)
throws NoSuchMethodException { throws NoSuchMethodException {
Objects.requireNonNull(name); Objects.requireNonNull(name);
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
}
Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes); Method method = searchMethods(privateGetDeclaredMethods(false), name, parameterTypes);
if (method == null) { if (method == null) {
throw new NoSuchMethodException(methodToString(name, parameterTypes)); throw new NoSuchMethodException(methodToString(name, parameterTypes));
@ -2703,15 +2484,8 @@ public final class Class<T> implements java.io.Serializable,
* @see #getConstructor(Class[]) * @see #getConstructor(Class[])
* @since 1.1 * @since 1.1
*/ */
@CallerSensitive
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
throws NoSuchMethodException { throws NoSuchMethodException {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
}
return getReflectionFactory().copyConstructor( return getReflectionFactory().copyConstructor(
getConstructor0(parameterTypes, Member.DECLARED)); getConstructor0(parameterTypes, Member.DECLARED));
} }
@ -2933,11 +2707,6 @@ public final class Class<T> implements java.io.Serializable,
* @since 1.2 * @since 1.2
*/ */
public ProtectionDomain getProtectionDomain() { public ProtectionDomain getProtectionDomain() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SecurityConstants.GET_PD_PERMISSION);
}
return protectionDomain(); return protectionDomain();
} }
@ -2972,91 +2741,6 @@ public final class Class<T> implements java.io.Serializable,
*/ */
static native <T> Class<T> getPrimitiveClass(String name); static native <T> Class<T> getPrimitiveClass(String name);
/*
* Check if client is allowed to access members. If access is denied,
* throw a SecurityException.
*
* This method also enforces package access.
*
* <p> Default policy: allow all clients access with normal Java access
* control.
*
* <p> NOTE: should only be called if a SecurityManager is installed
*/
private void checkMemberAccess(@SuppressWarnings("removal") SecurityManager sm, int which,
Class<?> caller, boolean checkProxyInterfaces) {
/* Default policy allows access to all {@link Member#PUBLIC} members,
* as well as access to classes that have the same class loader as the caller.
* In all other cases, it requires RuntimePermission("accessDeclaredMembers")
* permission.
*/
final ClassLoader ccl = ClassLoader.getClassLoader(caller);
if (which != Member.PUBLIC) {
final ClassLoader cl = classLoader;
if (ccl != cl) {
sm.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
}
}
this.checkPackageAccess(sm, ccl, checkProxyInterfaces);
}
/*
* Checks if a client loaded in ClassLoader ccl is allowed to access this
* class under the current package access policy. If access is denied,
* throw a SecurityException.
*
* NOTE: this method should only be called if a SecurityManager is active
*/
private void checkPackageAccess(@SuppressWarnings("removal") SecurityManager sm, final ClassLoader ccl,
boolean checkProxyInterfaces) {
final ClassLoader cl = classLoader;
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
String pkg = this.getPackageName();
if (!pkg.isEmpty()) {
// skip the package access check on a proxy class in default proxy package
if (!Proxy.isProxyClass(this) || ReflectUtil.isNonPublicProxyClass(this)) {
sm.checkPackageAccess(pkg);
}
}
}
// check package access on the proxy interfaces
if (checkProxyInterfaces && Proxy.isProxyClass(this)) {
ReflectUtil.checkProxyPackageAccess(ccl, this.getInterfaces(/* cloneArray */ false));
}
}
/*
* Checks if a client loaded in ClassLoader ccl is allowed to access the provided
* classes under the current package access policy. If access is denied,
* throw a SecurityException.
*
* NOTE: this method should only be called if a SecurityManager is active
* classes must be non-empty
* all classes provided must be loaded by the same ClassLoader
* NOTE: this method does not support Proxy classes
*/
private static void checkPackageAccessForPermittedSubclasses(@SuppressWarnings("removal") SecurityManager sm,
final ClassLoader ccl, Class<?>[] subClasses) {
final ClassLoader cl = subClasses[0].classLoader;
if (ReflectUtil.needsPackageAccessCheck(ccl, cl)) {
Set<String> packages = new HashSet<>();
for (Class<?> c : subClasses) {
if (Proxy.isProxyClass(c))
throw new InternalError("a permitted subclass should not be a proxy class: " + c);
String pkg = c.getPackageName();
if (!pkg.isEmpty()) {
packages.add(pkg);
}
}
for (String pkg : packages) {
sm.checkPackageAccess(pkg);
}
}
}
/** /**
* Add a package name prefix if the name is not absolute. Remove leading "/" * Add a package name prefix if the name is not absolute. Remove leading "/"
* if name is absolute * if name is absolute
@ -3732,15 +3416,12 @@ public final class Class<T> implements java.io.Serializable,
} }
// Fetches the factory for reflective objects // Fetches the factory for reflective objects
@SuppressWarnings("removal")
private static ReflectionFactory getReflectionFactory() { private static ReflectionFactory getReflectionFactory() {
var factory = reflectionFactory; var factory = reflectionFactory;
if (factory != null) { if (factory != null) {
return factory; return factory;
} }
return reflectionFactory = return reflectionFactory = ReflectionFactory.getReflectionFactory();
java.security.AccessController.doPrivileged
(new ReflectionFactory.GetReflectionFactoryAction());
} }
private static ReflectionFactory reflectionFactory; private static ReflectionFactory reflectionFactory;
@ -3766,20 +3447,13 @@ public final class Class<T> implements java.io.Serializable,
* identical to getEnumConstants except that the result is * identical to getEnumConstants except that the result is
* uncloned, cached, and shared by all callers. * uncloned, cached, and shared by all callers.
*/ */
@SuppressWarnings("removal")
T[] getEnumConstantsShared() { T[] getEnumConstantsShared() {
T[] constants = enumConstants; T[] constants = enumConstants;
if (constants == null) { if (constants == null) {
if (!isEnum()) return null; if (!isEnum()) return null;
try { try {
final Method values = getMethod("values"); final Method values = getMethod("values");
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<>() {
public Void run() {
values.setAccessible(true); values.setAccessible(true);
return null;
}
});
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
T[] temporaryConstants = (T[])values.invoke(null); T[] temporaryConstants = (T[])values.invoke(null);
enumConstants = constants = temporaryConstants; enumConstants = constants = temporaryConstants;
@ -4160,24 +3834,11 @@ public final class Class<T> implements java.io.Serializable,
* @jvms 4.7.29 The {@code NestMembers} Attribute * @jvms 4.7.29 The {@code NestMembers} Attribute
* @jvms 5.4.4 Access Control * @jvms 5.4.4 Access Control
*/ */
@CallerSensitive
public Class<?> getNestHost() { public Class<?> getNestHost() {
if (isPrimitive() || isArray()) { if (isPrimitive() || isArray()) {
return this; return this;
} }
return getNestHost0();
Class<?> host = getNestHost0();
if (host == this) {
return this;
}
// returning a different class requires a security check
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkPackageAccess(sm,
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
}
return host;
} }
/** /**
@ -4244,7 +3905,6 @@ public final class Class<T> implements java.io.Serializable,
* @jvms 4.7.28 The {@code NestHost} Attribute * @jvms 4.7.28 The {@code NestHost} Attribute
* @jvms 4.7.29 The {@code NestMembers} Attribute * @jvms 4.7.29 The {@code NestMembers} Attribute
*/ */
@CallerSensitive
public Class<?>[] getNestMembers() { public Class<?>[] getNestMembers() {
if (isPrimitive() || isArray()) { if (isPrimitive() || isArray()) {
return new Class<?>[] { this }; return new Class<?>[] { this };
@ -4252,17 +3912,6 @@ public final class Class<T> implements java.io.Serializable,
Class<?>[] members = getNestMembers0(); Class<?>[] members = getNestMembers0();
// Can't actually enable this due to bootstrapping issues // Can't actually enable this due to bootstrapping issues
// assert(members.length != 1 || members[0] == this); // expected invariant from VM // assert(members.length != 1 || members[0] == this); // expected invariant from VM
if (members.length > 1) {
// If we return anything other than the current class we need
// a security check
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkPackageAccess(sm,
ClassLoader.getClassLoader(Reflection.getCallerClass()), true);
}
}
return members; return members;
} }
@ -4432,7 +4081,6 @@ public final class Class<T> implements java.io.Serializable,
* @jls 9.1 Interface Declarations * @jls 9.1 Interface Declarations
* @since 17 * @since 17
*/ */
@CallerSensitive
public Class<?>[] getPermittedSubclasses() { public Class<?>[] getPermittedSubclasses() {
Class<?>[] subClasses; Class<?>[] subClasses;
if (isArray() || isPrimitive() || (subClasses = getPermittedSubclasses0()) == null) { if (isArray() || isPrimitive() || (subClasses = getPermittedSubclasses0()) == null) {
@ -4445,16 +4093,6 @@ public final class Class<T> implements java.io.Serializable,
.toArray(s -> new Class<?>[s]); .toArray(s -> new Class<?>[s]);
} }
} }
if (subClasses.length > 0) {
// If we return some classes we need a security check:
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkPackageAccessForPermittedSubclasses(sm,
ClassLoader.getClassLoader(Reflection.getCallerClass()),
subClasses);
}
}
return subClasses; return subClasses;
} }

View File

@ -39,8 +39,6 @@ import java.lang.reflect.AccessFlag;
import java.lang.reflect.AnnotatedElement; import java.lang.reflect.AnnotatedElement;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -64,14 +62,12 @@ import jdk.internal.misc.CDS;
import jdk.internal.misc.Unsafe; import jdk.internal.misc.Unsafe;
import jdk.internal.misc.VM; import jdk.internal.misc.VM;
import jdk.internal.module.ModuleBootstrap; import jdk.internal.module.ModuleBootstrap;
import jdk.internal.module.ModuleBootstrap.IllegalNativeAccess;
import jdk.internal.module.ModuleLoaderMap; import jdk.internal.module.ModuleLoaderMap;
import jdk.internal.module.ServicesCatalog; import jdk.internal.module.ServicesCatalog;
import jdk.internal.module.Resources; import jdk.internal.module.Resources;
import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection; import jdk.internal.reflect.Reflection;
import jdk.internal.vm.annotation.Stable; import jdk.internal.vm.annotation.Stable;
import sun.security.util.SecurityConstants;
/** /**
* Represents a run-time module, either {@link #isNamed() named} or unnamed. * Represents a run-time module, either {@link #isNamed() named} or unnamed.
@ -198,11 +194,6 @@ public final class Module implements AnnotatedElement {
* @return The class loader for this module * @return The class loader for this module
*/ */
public ClassLoader getClassLoader() { public ClassLoader getClassLoader() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
return loader; return loader;
} }
@ -1556,7 +1547,6 @@ public final class Module implements AnnotatedElement {
// cached class file with annotations // cached class file with annotations
private volatile Class<?> moduleInfoClass; private volatile Class<?> moduleInfoClass;
@SuppressWarnings("removal")
private Class<?> moduleInfoClass() { private Class<?> moduleInfoClass() {
Class<?> clazz = this.moduleInfoClass; Class<?> clazz = this.moduleInfoClass;
if (clazz != null) if (clazz != null)
@ -1566,8 +1556,7 @@ public final class Module implements AnnotatedElement {
clazz = this.moduleInfoClass; clazz = this.moduleInfoClass;
if (clazz == null) { if (clazz == null) {
if (isNamed()) { if (isNamed()) {
PrivilegedAction<Class<?>> pa = this::loadModuleInfoClass; clazz = loadModuleInfoClass();
clazz = AccessController.doPrivileged(pa);
} }
if (clazz == null) { if (clazz == null) {
class DummyModuleInfo { } class DummyModuleInfo { }

View File

@ -44,7 +44,6 @@ import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import jdk.internal.javac.PreviewFeature;
import jdk.internal.javac.Restricted; import jdk.internal.javac.Restricted;
import jdk.internal.loader.ClassLoaderValue; import jdk.internal.loader.ClassLoaderValue;
import jdk.internal.loader.Loader; import jdk.internal.loader.Loader;
@ -54,7 +53,6 @@ import jdk.internal.misc.CDS;
import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection; import jdk.internal.reflect.Reflection;
import jdk.internal.vm.annotation.Stable; import jdk.internal.vm.annotation.Stable;
import sun.security.util.SecurityConstants;
/** /**
* A layer of modules in the Java virtual machine. * A layer of modules in the Java virtual machine.
@ -505,9 +503,6 @@ public final class ModuleLayer {
List<ModuleLayer> parents = List.copyOf(parentLayers); List<ModuleLayer> parents = List.copyOf(parentLayers);
checkConfiguration(cf, parents); checkConfiguration(cf, parents);
checkCreateClassLoaderPermission();
checkGetClassLoaderPermission();
try { try {
Loader loader = new Loader(cf.modules(), parentLoader); Loader loader = new Loader(cf.modules(), parentLoader);
loader.initRemotePackageMap(cf, parents); loader.initRemotePackageMap(cf, parents);
@ -572,9 +567,6 @@ public final class ModuleLayer {
List<ModuleLayer> parents = List.copyOf(parentLayers); List<ModuleLayer> parents = List.copyOf(parentLayers);
checkConfiguration(cf, parents); checkConfiguration(cf, parents);
checkCreateClassLoaderPermission();
checkGetClassLoaderPermission();
LoaderPool pool = new LoaderPool(cf, parents, parentLoader); LoaderPool pool = new LoaderPool(cf, parents, parentLoader);
try { try {
ModuleLayer layer = new ModuleLayer(cf, parents, pool::loaderFor); ModuleLayer layer = new ModuleLayer(cf, parents, pool::loaderFor);
@ -654,8 +646,6 @@ public final class ModuleLayer {
checkConfiguration(cf, parents); checkConfiguration(cf, parents);
Objects.requireNonNull(clf); Objects.requireNonNull(clf);
checkGetClassLoaderPermission();
// The boot layer is checked during module system initialization // The boot layer is checked during module system initialization
if (boot() != null) { if (boot() != null) {
checkForDuplicatePkgs(cf, clf); checkForDuplicatePkgs(cf, clf);
@ -693,20 +683,6 @@ public final class ModuleLayer {
} }
} }
private static void checkCreateClassLoaderPermission() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);
}
private static void checkGetClassLoaderPermission() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
/** /**
* Checks a configuration and the module-to-loader mapping to ensure that * Checks a configuration and the module-to-loader mapping to ensure that
* no two modules mapped to the same class loader have the same package. * no two modules mapped to the same class loader have the same package.

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 1997, 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
@ -30,8 +30,6 @@ import java.lang.reflect.AnnotatedElement;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URL; import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Objects; import java.util.Objects;
import jdk.internal.loader.BootLoader; import jdk.internal.loader.BootLoader;
@ -417,9 +415,7 @@ public class Package extends NamedPackage implements java.lang.reflect.Annotated
// find package-info.class defined by loader // find package-info.class defined by loader
String cn = packageName() + ".package-info"; String cn = packageName() + ".package-info";
Module module = module(); Module module = module();
PrivilegedAction<ClassLoader> pa = module::getClassLoader; ClassLoader loader = module.getClassLoader();
@SuppressWarnings("removal")
ClassLoader loader = AccessController.doPrivileged(pa);
Class<?> c; Class<?> c;
if (loader != null) { if (loader != null) {
c = loader.loadClass(module, cn); c = loader.loadClass(module, cn);

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016, 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
@ -28,7 +28,6 @@ import jdk.internal.reflect.ReflectionFactory;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.util.Arrays; import java.util.Arrays;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
@ -88,10 +87,7 @@ final class PublicMethods {
* Method (name, parameter types) tuple. * Method (name, parameter types) tuple.
*/ */
private static final class Key { private static final class Key {
@SuppressWarnings("removal") private static final ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
private static final ReflectionFactory reflectionFactory =
AccessController.doPrivileged(
new ReflectionFactory.GetReflectionFactoryAction());
private final String name; // must be interned (as from Method.getName()) private final String name; // must be interned (as from Method.getName())
private final Class<?>[] ptypes; private final Class<?>[] ptypes;

View File

@ -107,9 +107,6 @@ import static sun.invoke.util.Wrapper.isWrapperType;
* implemented by invoking the implementation method * implemented by invoking the implementation method
* @throws LambdaConversionException If any of the meta-factory protocol * @throws LambdaConversionException If any of the meta-factory protocol
* invariants are violated * invariants are violated
* @throws SecurityException If a security manager is present, and it
* <a href="MethodHandles.Lookup.html#secmgr">denies access</a>
* from {@code caller} to the package of {@code implementation}.
*/ */
AbstractValidatingLambdaMetafactory(MethodHandles.Lookup caller, AbstractValidatingLambdaMetafactory(MethodHandles.Lookup caller,
MethodType factoryType, MethodType factoryType,
@ -138,7 +135,7 @@ import static sun.invoke.util.Wrapper.isWrapperType;
this.implementation = implementation; this.implementation = implementation;
this.implMethodType = implementation.type(); this.implMethodType = implementation.type();
try { try {
this.implInfo = caller.revealDirect(implementation); // may throw SecurityException this.implInfo = caller.revealDirect(implementation);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
throw new LambdaConversionException(implementation + " is not direct or cannot be cracked"); throw new LambdaConversionException(implementation + " is not direct or cannot be cracked");
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 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,7 +25,6 @@
package java.lang.invoke; package java.lang.invoke;
import java.security.*;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodHandles.Lookup;
@ -85,16 +84,13 @@ final class InfoFromMemberName implements MethodHandleInfo {
// For more information see comments on {@link MethodHandleNatives#linkMethod}. // For more information see comments on {@link MethodHandleNatives#linkMethod}.
throw new IllegalArgumentException("cannot reflect signature polymorphic method"); throw new IllegalArgumentException("cannot reflect signature polymorphic method");
} }
@SuppressWarnings("removal")
Member mem = AccessController.doPrivileged(new PrivilegedAction<>() { Member mem;
public Member run() {
try { try {
return reflectUnchecked(); mem = reflectUnchecked();
} catch (ReflectiveOperationException ex) { } catch (ReflectiveOperationException ex) {
throw new IllegalArgumentException(ex); throw new IllegalArgumentException(ex);
} }
}
});
try { try {
Class<?> defc = getDeclaringClass(); Class<?> defc = getDeclaringClass();
byte refKind = (byte) getReferenceKind(); byte refKind = (byte) getReferenceKind();

View File

@ -29,7 +29,6 @@ import jdk.internal.constant.ClassOrInterfaceDescImpl;
import jdk.internal.misc.CDS; import jdk.internal.misc.CDS;
import jdk.internal.util.ClassFileDumper; import jdk.internal.util.ClassFileDumper;
import sun.invoke.util.VerifyAccess; import sun.invoke.util.VerifyAccess;
import sun.security.action.GetBooleanAction;
import java.io.Serializable; import java.io.Serializable;
import java.lang.classfile.ClassBuilder; import java.lang.classfile.ClassBuilder;
@ -83,7 +82,7 @@ import sun.invoke.util.Wrapper;
lambdaProxyClassFileDumper = ClassFileDumper.getInstance(dumpProxyClassesKey, "DUMP_LAMBDA_PROXY_CLASS_FILES"); lambdaProxyClassFileDumper = ClassFileDumper.getInstance(dumpProxyClassesKey, "DUMP_LAMBDA_PROXY_CLASS_FILES");
final String disableEagerInitializationKey = "jdk.internal.lambda.disableEagerInitialization"; final String disableEagerInitializationKey = "jdk.internal.lambda.disableEagerInitialization";
disableEagerInitialization = GetBooleanAction.privilegedGetProperty(disableEagerInitializationKey); disableEagerInitialization = Boolean.getBoolean(disableEagerInitializationKey);
} }
// See context values in AbstractValidatingLambdaMetafactory // See context values in AbstractValidatingLambdaMetafactory
@ -134,9 +133,6 @@ import sun.invoke.util.Wrapper;
* implemented by invoking the implementation method * implemented by invoking the implementation method
* @throws LambdaConversionException If any of the meta-factory protocol * @throws LambdaConversionException If any of the meta-factory protocol
* invariants are violated * invariants are violated
* @throws SecurityException If a security manager is present, and it
* <a href="MethodHandles.Lookup.html#secmgr">denies access</a>
* from {@code caller} to the package of {@code implementation}.
*/ */
public InnerClassLambdaMetafactory(MethodHandles.Lookup caller, public InnerClassLambdaMetafactory(MethodHandles.Lookup caller,
MethodType factoryType, MethodType factoryType,

View File

@ -1208,11 +1208,7 @@ abstract class MethodHandleImpl {
private static boolean checkInjectedInvoker(Class<?> hostClass, Class<?> invokerClass) { private static boolean checkInjectedInvoker(Class<?> hostClass, Class<?> invokerClass) {
assert (hostClass.getClassLoader() == invokerClass.getClassLoader()) : hostClass.getName()+" (CL)"; assert (hostClass.getClassLoader() == invokerClass.getClassLoader()) : hostClass.getName()+" (CL)";
try {
assert (hostClass.getProtectionDomain() == invokerClass.getProtectionDomain()) : hostClass.getName()+" (PD)"; assert (hostClass.getProtectionDomain() == invokerClass.getProtectionDomain()) : hostClass.getName()+" (PD)";
} catch (SecurityException ex) {
// Self-check was blocked by security manager. This is OK.
}
try { try {
// Test the invoker to ensure that it really injects into the right place. // Test the invoker to ensure that it really injects into the right place.
MethodHandle invoker = IMPL_LOOKUP.findStatic(invokerClass, "invoke_V", INVOKER_MT); MethodHandle invoker = IMPL_LOOKUP.findStatic(invokerClass, "invoke_V", INVOKER_MT);

View File

@ -33,8 +33,6 @@ import java.lang.ref.WeakReference;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.lang.reflect.UndeclaredThrowableException; import java.lang.reflect.UndeclaredThrowableException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -56,10 +54,7 @@ import java.lang.classfile.TypeKind;
import jdk.internal.constant.ConstantUtils; import jdk.internal.constant.ConstantUtils;
import jdk.internal.loader.ClassLoaders; import jdk.internal.loader.ClassLoaders;
import jdk.internal.module.Modules; import jdk.internal.module.Modules;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import jdk.internal.util.ClassFileDumper; import jdk.internal.util.ClassFileDumper;
import sun.reflect.misc.ReflectUtil;
import static java.lang.constant.ConstantDescs.*; import static java.lang.constant.ConstantDescs.*;
import static java.lang.invoke.MethodHandleStatics.*; import static java.lang.invoke.MethodHandleStatics.*;
@ -159,7 +154,6 @@ public class MethodHandleProxies {
* be converted to the type required by the requested interface * be converted to the type required by the requested interface
*/ */
@SuppressWarnings("doclint:reference") // cross-module links @SuppressWarnings("doclint:reference") // cross-module links
@CallerSensitive
public static <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) { public static <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers())) if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
throw newIllegalArgumentException("not a public interface", intfc.getName()); throw newIllegalArgumentException("not a public interface", intfc.getName());
@ -168,17 +162,7 @@ public class MethodHandleProxies {
if (intfc.isHidden()) if (intfc.isHidden())
throw newIllegalArgumentException("a hidden interface", intfc.getName()); throw newIllegalArgumentException("a hidden interface", intfc.getName());
Objects.requireNonNull(target); Objects.requireNonNull(target);
final MethodHandle mh; final MethodHandle mh = target;
@SuppressWarnings("removal")
var sm = System.getSecurityManager();
if (sm != null) {
final Class<?> caller = Reflection.getCallerClass();
final ClassLoader ccl = caller != null ? caller.getClassLoader() : null;
ReflectUtil.checkProxyPackageAccess(ccl, intfc);
mh = ccl != null ? bindCaller(target, caller) : target;
} else {
mh = target;
}
// Define one hidden class for each interface. Create an instance of // Define one hidden class for each interface. Create an instance of
// the hidden class for a given target method handle which will be // the hidden class for a given target method handle which will be
@ -283,17 +267,7 @@ public class MethodHandleProxies {
// define the dynamic module to the class loader of the interface // define the dynamic module to the class loader of the interface
var definer = new Lookup(intfc).makeHiddenClassDefiner(className, template, DUMPER); var definer = new Lookup(intfc).makeHiddenClassDefiner(className, template, DUMPER);
@SuppressWarnings("removal") Lookup lookup = definer.defineClassAsLookup(true);
var sm = System.getSecurityManager();
Lookup lookup;
if (sm != null) {
@SuppressWarnings("removal")
var l = AccessController.doPrivileged((PrivilegedAction<Lookup>) () ->
definer.defineClassAsLookup(true));
lookup = l;
} else {
lookup = definer.defineClassAsLookup(true);
}
// cache the wrapper type // cache the wrapper type
var ret = lookup.lookupClass(); var ret = lookup.lookupClass();
WRAPPER_TYPES.add(ret); WRAPPER_TYPES.add(ret);

View File

@ -28,7 +28,6 @@ package java.lang.invoke;
import jdk.internal.misc.CDS; import jdk.internal.misc.CDS;
import jdk.internal.misc.Unsafe; import jdk.internal.misc.Unsafe;
import jdk.internal.util.ClassFileDumper; import jdk.internal.util.ClassFileDumper;
import sun.security.action.GetPropertyAction;
import java.lang.reflect.ClassFileFormatVersion; import java.lang.reflect.ClassFileFormatVersion;
import java.util.Properties; import java.util.Properties;
@ -66,7 +65,7 @@ class MethodHandleStatics {
static final ClassFileDumper DUMP_CLASS_FILES; static final ClassFileDumper DUMP_CLASS_FILES;
static { static {
Properties props = GetPropertyAction.privilegedGetProperties(); Properties props = System.getProperties();
DEBUG_METHOD_HANDLE_NAMES = Boolean.parseBoolean( DEBUG_METHOD_HANDLE_NAMES = Boolean.parseBoolean(
props.getProperty("java.lang.invoke.MethodHandle.DEBUG_NAMES")); props.getProperty("java.lang.invoke.MethodHandle.DEBUG_NAMES"));

View File

@ -36,8 +36,6 @@ import jdk.internal.vm.annotation.ForceInline;
import sun.invoke.util.ValueConversions; import sun.invoke.util.ValueConversions;
import sun.invoke.util.VerifyAccess; import sun.invoke.util.VerifyAccess;
import sun.invoke.util.Wrapper; import sun.invoke.util.Wrapper;
import sun.reflect.misc.ReflectUtil;
import sun.security.util.SecurityConstants;
import java.lang.classfile.ClassFile; import java.lang.classfile.ClassFile;
import java.lang.classfile.ClassModel; import java.lang.classfile.ClassModel;
@ -243,9 +241,6 @@ public class MethodHandles {
return new Lookup(targetClass); return new Lookup(targetClass);
} }
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) sm.checkPermission(SecurityConstants.ACCESS_PERMISSION);
if (targetClass.isPrimitive()) if (targetClass.isPrimitive())
throw new IllegalArgumentException(targetClass + " is a primitive class"); throw new IllegalArgumentException(targetClass + " is a primitive class");
if (targetClass.isArray()) if (targetClass.isArray())
@ -463,9 +458,6 @@ public class MethodHandles {
* @since 1.8 * @since 1.8
*/ */
public static <T extends Member> T reflectAs(Class<T> expected, MethodHandle target) { public static <T extends Member> T reflectAs(Class<T> expected, MethodHandle target) {
@SuppressWarnings("removal")
SecurityManager smgr = System.getSecurityManager();
if (smgr != null) smgr.checkPermission(SecurityConstants.ACCESS_PERMISSION);
Lookup lookup = Lookup.IMPL_LOOKUP; // use maximally privileged lookup Lookup lookup = Lookup.IMPL_LOOKUP; // use maximally privileged lookup
return lookup.revealDirect(target).reflectAs(expected, lookup); return lookup.revealDirect(target).reflectAs(expected, lookup);
} }
@ -741,8 +733,6 @@ public class MethodHandles {
* <ul style="font-size:smaller;"> * <ul style="font-size:smaller;">
* <li>access private fields, methods, and constructors of the lookup class and its nestmates * <li>access private fields, methods, and constructors of the lookup class and its nestmates
* <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions * <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions
* <li>avoid <a href="MethodHandles.Lookup.html#secmgr">package access checks</a>
* for classes accessible to the lookup class
* <li>create {@link Lookup#in delegated lookup objects} which have private access to other classes * <li>create {@link Lookup#in delegated lookup objects} which have private access to other classes
* within the same package member * within the same package member
* </ul> * </ul>
@ -1759,23 +1749,11 @@ public class MethodHandles {
* @see ClassLoader#defineClass(String,byte[],int,int,ProtectionDomain) * @see ClassLoader#defineClass(String,byte[],int,int,ProtectionDomain)
*/ */
public Class<?> defineClass(byte[] bytes) throws IllegalAccessException { public Class<?> defineClass(byte[] bytes) throws IllegalAccessException {
ensureDefineClassPermission();
if ((lookupModes() & PACKAGE) == 0) if ((lookupModes() & PACKAGE) == 0)
throw new IllegalAccessException("Lookup does not have PACKAGE access"); throw new IllegalAccessException("Lookup does not have PACKAGE access");
return makeClassDefiner(bytes.clone()).defineClass(false); return makeClassDefiner(bytes.clone()).defineClass(false);
} }
private void ensureDefineClassPermission() {
if (allowedModes == TRUSTED) return;
if (!hasFullPrivilegeAccess()) {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null)
sm.checkPermission(new RuntimePermission("defineClass"));
}
}
/** /**
* The set of class options that specify whether a hidden class created by * The set of class options that specify whether a hidden class created by
* {@link Lookup#defineHiddenClass(byte[], boolean, ClassOption...) * {@link Lookup#defineHiddenClass(byte[], boolean, ClassOption...)
@ -2042,7 +2020,6 @@ public class MethodHandles {
{ {
Objects.requireNonNull(bytes); Objects.requireNonNull(bytes);
int flags = ClassOption.optionsToFlag(options); int flags = ClassOption.optionsToFlag(options);
ensureDefineClassPermission();
if (!hasFullPrivilegeAccess()) { if (!hasFullPrivilegeAccess()) {
throw new IllegalAccessException(this + " does not have full privilege access"); throw new IllegalAccessException(this + " does not have full privilege access");
} }
@ -2128,7 +2105,6 @@ public class MethodHandles {
int flags = ClassOption.optionsToFlag(options); int flags = ClassOption.optionsToFlag(options);
ensureDefineClassPermission();
if (!hasFullPrivilegeAccess()) { if (!hasFullPrivilegeAccess()) {
throw new IllegalAccessException(this + " does not have full privilege access"); throw new IllegalAccessException(this + " does not have full privilege access");
} }
@ -2768,7 +2744,6 @@ assertEquals("[x, y, z]", pb.command().toString());
if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, prevLookupClass, allowedModes)) { if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, prevLookupClass, allowedModes)) {
throw makeAccessException(targetClass); throw makeAccessException(targetClass);
} }
checkSecurityManager(targetClass);
// ensure class initialization // ensure class initialization
Unsafe.getUnsafe().ensureClassInitialized(targetClass); Unsafe.getUnsafe().ensureClassInitialized(targetClass);
@ -2872,7 +2847,6 @@ assertEquals("[x, y, z]", pb.command().toString());
if (!isClassAccessible(targetClass)) { if (!isClassAccessible(targetClass)) {
throw makeAccessException(targetClass); throw makeAccessException(targetClass);
} }
checkSecurityManager(targetClass);
return targetClass; return targetClass;
} }
@ -3292,7 +3266,7 @@ return mh1;
assert(method.isMethod()); assert(method.isMethod());
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this; Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
return lookup.getDirectMethodNoSecurityManager(refKind, method.getDeclaringClass(), method, findBoundCallerLookup(method)); return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method, findBoundCallerLookup(method));
} }
private MethodHandle unreflectForMH(Method m) { private MethodHandle unreflectForMH(Method m) {
// these names require special lookups because they throw UnsupportedOperationException // these names require special lookups because they throw UnsupportedOperationException
@ -3343,7 +3317,7 @@ return mh1;
MemberName method = new MemberName(m, true); MemberName method = new MemberName(m, true);
assert(method.isMethod()); assert(method.isMethod());
// ignore m.isAccessible: this is a new kind of access // ignore m.isAccessible: this is a new kind of access
return specialLookup.getDirectMethodNoSecurityManager(REF_invokeSpecial, method.getDeclaringClass(), method, findBoundCallerLookup(method)); return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method, findBoundCallerLookup(method));
} }
/** /**
@ -3375,12 +3349,12 @@ return mh1;
assert(ctor.isConstructor()); assert(ctor.isConstructor());
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this; Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor); return lookup.getDirectConstructor(ctor.getDeclaringClass(), ctor);
} }
/* /*
* Produces a method handle that is capable of creating instances of the given class * Produces a method handle that is capable of creating instances of the given class
* and instantiated by the given constructor. No security manager check. * and instantiated by the given constructor.
* *
* This method should only be used by ReflectionFactory::newConstructorForSerialization. * This method should only be used by ReflectionFactory::newConstructorForSerialization.
*/ */
@ -3473,7 +3447,7 @@ return mh1;
: MethodHandleNatives.refKindIsGetter(field.getReferenceKind())); : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this; Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
return lookup.getDirectFieldNoSecurityManager(field.getReferenceKind(), f.getDeclaringClass(), field); return lookup.getDirectField(field.getReferenceKind(), f.getDeclaringClass(), field);
} }
/** /**
@ -3550,7 +3524,7 @@ return mh1;
public VarHandle unreflectVarHandle(Field f) throws IllegalAccessException { public VarHandle unreflectVarHandle(Field f) throws IllegalAccessException {
MemberName getField = new MemberName(f, false); MemberName getField = new MemberName(f, false);
MemberName putField = new MemberName(f, true); MemberName putField = new MemberName(f, true);
return getFieldVarHandleNoSecurityManager(getField.getReferenceKind(), putField.getReferenceKind(), return getFieldVarHandle(getField.getReferenceKind(), putField.getReferenceKind(),
f.getDeclaringClass(), getField, putField); f.getDeclaringClass(), getField, putField);
} }
@ -3586,10 +3560,9 @@ return mh1;
if (refKind == REF_invokeVirtual && defc.isInterface()) if (refKind == REF_invokeVirtual && defc.isInterface())
// Symbolic reference is through interface but resolves to Object method (toString, etc.) // Symbolic reference is through interface but resolves to Object method (toString, etc.)
refKind = REF_invokeInterface; refKind = REF_invokeInterface;
// Check SM permissions and member access before cracking. // Check member access before cracking.
try { try {
checkAccess(refKind, defc, member); checkAccess(refKind, defc, member);
checkSecurityManager(defc, member);
} catch (IllegalAccessException ex) { } catch (IllegalAccessException ex) {
throw new IllegalArgumentException(ex); throw new IllegalArgumentException(ex);
} }
@ -3716,69 +3689,6 @@ return mh1;
return (allowedModes & (PRIVATE|MODULE)) == (PRIVATE|MODULE); return (allowedModes & (PRIVATE|MODULE)) == (PRIVATE|MODULE);
} }
/**
* Perform steps 1 and 2b <a href="MethodHandles.Lookup.html#secmgr">access checks</a>
* for ensureInitialized, findClass or accessClass.
*/
void checkSecurityManager(Class<?> refc) {
if (allowedModes == TRUSTED) return;
@SuppressWarnings("removal")
SecurityManager smgr = System.getSecurityManager();
if (smgr == null) return;
// Step 1:
boolean fullPrivilegeLookup = hasFullPrivilegeAccess();
if (!fullPrivilegeLookup ||
!VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
ReflectUtil.checkPackageAccess(refc);
}
// Step 2b:
if (!fullPrivilegeLookup) {
smgr.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
/**
* Perform steps 1, 2a and 3 <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
* Determines a trustable caller class to compare with refc, the symbolic reference class.
* If this lookup object has full privilege access except original access,
* then the caller class is the lookupClass.
*
* Lookup object created by {@link MethodHandles#privateLookupIn(Class, Lookup)}
* from the same module skips the security permission check.
*/
void checkSecurityManager(Class<?> refc, MemberName m) {
Objects.requireNonNull(refc);
Objects.requireNonNull(m);
if (allowedModes == TRUSTED) return;
@SuppressWarnings("removal")
SecurityManager smgr = System.getSecurityManager();
if (smgr == null) return;
// Step 1:
boolean fullPrivilegeLookup = hasFullPrivilegeAccess();
if (!fullPrivilegeLookup ||
!VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
ReflectUtil.checkPackageAccess(refc);
}
// Step 2a:
if (m.isPublic()) return;
if (!fullPrivilegeLookup) {
smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
}
// Step 3:
Class<?> defc = m.getDeclaringClass();
if (!fullPrivilegeLookup && defc != refc) {
ReflectUtil.checkPackageAccess(defc);
}
}
void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException { void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
boolean wantStatic = (refKind == REF_invokeStatic); boolean wantStatic = (refKind == REF_invokeStatic);
String message; String message;
@ -3918,30 +3828,18 @@ return mh1;
/** Check access and get the requested method. */ /** Check access and get the requested method. */
private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException { private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
final boolean doRestrict = true; final boolean doRestrict = true;
final boolean checkSecurity = true; return getDirectMethodCommon(refKind, refc, method, doRestrict, callerLookup);
return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerLookup);
} }
/** Check access and get the requested method, for invokespecial with no restriction on the application of narrowing rules. */ /** Check access and get the requested method, for invokespecial with no restriction on the application of narrowing rules. */
private MethodHandle getDirectMethodNoRestrictInvokeSpecial(Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException { private MethodHandle getDirectMethodNoRestrictInvokeSpecial(Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
final boolean doRestrict = false; final boolean doRestrict = false;
final boolean checkSecurity = true; return getDirectMethodCommon(REF_invokeSpecial, refc, method, doRestrict, callerLookup);
return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, callerLookup);
}
/** Check access and get the requested method, eliding security manager checks. */
private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
final boolean doRestrict = true;
final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerLookup);
} }
/** Common code for all methods; do not call directly except from immediately above. */ /** Common code for all methods; do not call directly except from immediately above. */
private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method, private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
boolean checkSecurity,
boolean doRestrict, boolean doRestrict,
Lookup boundCaller) throws IllegalAccessException { Lookup boundCaller) throws IllegalAccessException {
checkMethod(refKind, refc, method); checkMethod(refKind, refc, method);
// Optionally check with the security manager; this isn't needed for unreflect* calls.
if (checkSecurity)
checkSecurityManager(refc, method);
assert(!method.isMethodHandleInvoke()); assert(!method.isMethodHandleInvoke());
if (refKind == REF_invokeSpecial && if (refKind == REF_invokeSpecial &&
@ -4010,21 +3908,11 @@ return mh1;
/** Check access and get the requested field. */ /** Check access and get the requested field. */
private MethodHandle getDirectField(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException { private MethodHandle getDirectField(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
final boolean checkSecurity = true; return getDirectFieldCommon(refKind, refc, field);
return getDirectFieldCommon(refKind, refc, field, checkSecurity);
}
/** Check access and get the requested field, eliding security manager checks. */
private MethodHandle getDirectFieldNoSecurityManager(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
return getDirectFieldCommon(refKind, refc, field, checkSecurity);
} }
/** Common code for all fields; do not call directly except from immediately above. */ /** Common code for all fields; do not call directly except from immediately above. */
private MethodHandle getDirectFieldCommon(byte refKind, Class<?> refc, MemberName field, private MethodHandle getDirectFieldCommon(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
boolean checkSecurity) throws IllegalAccessException {
checkField(refKind, refc, field); checkField(refKind, refc, field);
// Optionally check with the security manager; this isn't needed for unreflect* calls.
if (checkSecurity)
checkSecurityManager(refc, field);
DirectMethodHandle dmh = DirectMethodHandle.make(refc, field); DirectMethodHandle dmh = DirectMethodHandle.make(refc, field);
boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(refKind) && boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(refKind) &&
restrictProtectedReceiver(field)); restrictProtectedReceiver(field));
@ -4035,26 +3923,17 @@ return mh1;
private VarHandle getFieldVarHandle(byte getRefKind, byte putRefKind, private VarHandle getFieldVarHandle(byte getRefKind, byte putRefKind,
Class<?> refc, MemberName getField, MemberName putField) Class<?> refc, MemberName getField, MemberName putField)
throws IllegalAccessException { throws IllegalAccessException {
final boolean checkSecurity = true; return getFieldVarHandleCommon(getRefKind, putRefKind, refc, getField, putField);
return getFieldVarHandleCommon(getRefKind, putRefKind, refc, getField, putField, checkSecurity);
}
private VarHandle getFieldVarHandleNoSecurityManager(byte getRefKind, byte putRefKind,
Class<?> refc, MemberName getField, MemberName putField)
throws IllegalAccessException {
final boolean checkSecurity = false;
return getFieldVarHandleCommon(getRefKind, putRefKind, refc, getField, putField, checkSecurity);
} }
private VarHandle getFieldVarHandleCommon(byte getRefKind, byte putRefKind, private VarHandle getFieldVarHandleCommon(byte getRefKind, byte putRefKind,
Class<?> refc, MemberName getField, MemberName putField, Class<?> refc, MemberName getField,
boolean checkSecurity) throws IllegalAccessException { MemberName putField) throws IllegalAccessException {
assert getField.isStatic() == putField.isStatic(); assert getField.isStatic() == putField.isStatic();
assert getField.isGetter() && putField.isSetter(); assert getField.isGetter() && putField.isSetter();
assert MethodHandleNatives.refKindIsStatic(getRefKind) == MethodHandleNatives.refKindIsStatic(putRefKind); assert MethodHandleNatives.refKindIsStatic(getRefKind) == MethodHandleNatives.refKindIsStatic(putRefKind);
assert MethodHandleNatives.refKindIsGetter(getRefKind) && MethodHandleNatives.refKindIsSetter(putRefKind); assert MethodHandleNatives.refKindIsGetter(getRefKind) && MethodHandleNatives.refKindIsSetter(putRefKind);
checkField(getRefKind, refc, getField); checkField(getRefKind, refc, getField);
if (checkSecurity)
checkSecurityManager(refc, getField);
if (!putField.isFinal()) { if (!putField.isFinal()) {
// A VarHandle does not support updates to final fields, any // A VarHandle does not support updates to final fields, any
@ -4062,8 +3941,6 @@ return mh1;
// therefore the following write-based accessibility checks are // therefore the following write-based accessibility checks are
// only required for non-final fields // only required for non-final fields
checkField(putRefKind, refc, putField); checkField(putRefKind, refc, putField);
if (checkSecurity)
checkSecurityManager(refc, putField);
} }
boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(getRefKind) && boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(getRefKind) &&
@ -4081,22 +3958,12 @@ return mh1;
} }
/** Check access and get the requested constructor. */ /** Check access and get the requested constructor. */
private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException { private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
final boolean checkSecurity = true; return getDirectConstructorCommon(refc, ctor);
return getDirectConstructorCommon(refc, ctor, checkSecurity);
}
/** Check access and get the requested constructor, eliding security manager checks. */
private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException {
final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
return getDirectConstructorCommon(refc, ctor, checkSecurity);
} }
/** Common code for all constructors; do not call directly except from immediately above. */ /** Common code for all constructors; do not call directly except from immediately above. */
private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor, private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor) throws IllegalAccessException {
boolean checkSecurity) throws IllegalAccessException {
assert(ctor.isConstructor()); assert(ctor.isConstructor());
checkAccess(REF_newInvokeSpecial, refc, ctor); checkAccess(REF_newInvokeSpecial, refc, ctor);
// Optionally check with the security manager; this isn't needed for unreflect* calls.
if (checkSecurity)
checkSecurityManager(refc, ctor);
assert(!MethodHandleNatives.isCallerSensitive(ctor)); // maybeBindCaller not relevant here assert(!MethodHandleNatives.isCallerSensitive(ctor)); // maybeBindCaller not relevant here
return DirectMethodHandle.make(ctor).setVarargs(ctor); return DirectMethodHandle.make(ctor).setVarargs(ctor);
} }
@ -4163,26 +4030,21 @@ return mh1;
return false; return false;
} }
} }
try {
MemberName resolved2 = publicLookup().resolveOrNull(refKind, MemberName resolved2 = publicLookup().resolveOrNull(refKind,
new MemberName(refKind, defc, member.getName(), member.getType())); new MemberName(refKind, defc, member.getName(), member.getType()));
if (resolved2 == null) { if (resolved2 == null) {
return false; return false;
} }
checkSecurityManager(defc, resolved2);
} catch (SecurityException ex) {
return false;
}
return true; return true;
} }
private MethodHandle getDirectMethodForConstant(byte refKind, Class<?> defc, MemberName member) private MethodHandle getDirectMethodForConstant(byte refKind, Class<?> defc, MemberName member)
throws ReflectiveOperationException { throws ReflectiveOperationException {
if (MethodHandleNatives.refKindIsField(refKind)) { if (MethodHandleNatives.refKindIsField(refKind)) {
return getDirectFieldNoSecurityManager(refKind, defc, member); return getDirectField(refKind, defc, member);
} else if (MethodHandleNatives.refKindIsMethod(refKind)) { } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
return getDirectMethodNoSecurityManager(refKind, defc, member, findBoundCallerLookup(member)); return getDirectMethod(refKind, defc, member, findBoundCallerLookup(member));
} else if (refKind == REF_newInvokeSpecial) { } else if (refKind == REF_newInvokeSpecial) {
return getDirectConstructorNoSecurityManager(defc, member); return getDirectConstructor(defc, member);
} }
// oops // oops
throw newIllegalArgumentException("bad MethodHandle constant #"+member); throw newIllegalArgumentException("bad MethodHandle constant #"+member);

View File

@ -28,21 +28,15 @@ package java.lang.invoke;
import java.lang.constant.ClassDesc; import java.lang.constant.ClassDesc;
import java.lang.constant.Constable; import java.lang.constant.Constable;
import java.lang.constant.MethodTypeDesc; import java.lang.constant.MethodTypeDesc;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.StringJoiner; import java.util.StringJoiner;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Stream;
import jdk.internal.util.ReferencedKeySet; import jdk.internal.util.ReferencedKeySet;
import jdk.internal.util.ReferenceKey; import jdk.internal.util.ReferenceKey;
@ -50,7 +44,6 @@ import jdk.internal.vm.annotation.Stable;
import sun.invoke.util.BytecodeDescriptor; import sun.invoke.util.BytecodeDescriptor;
import sun.invoke.util.VerifyType; import sun.invoke.util.VerifyType;
import sun.invoke.util.Wrapper; import sun.invoke.util.Wrapper;
import sun.security.util.SecurityConstants;
import static java.lang.invoke.MethodHandleStatics.UNSAFE; import static java.lang.invoke.MethodHandleStatics.UNSAFE;
import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException; import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
@ -1183,13 +1176,6 @@ class MethodType
public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader) public static MethodType fromMethodDescriptorString(String descriptor, ClassLoader loader)
throws IllegalArgumentException, TypeNotPresentException throws IllegalArgumentException, TypeNotPresentException
{ {
if (loader == null) {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
}
return fromDescriptor(descriptor, return fromDescriptor(descriptor,
(loader == null) ? ClassLoader.getSystemClassLoader() : loader); (loader == null) ? ClassLoader.getSystemClassLoader() : loader);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 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
@ -28,9 +28,6 @@ import java.io.Serializable;
import java.io.InvalidObjectException; import java.io.InvalidObjectException;
import java.io.ObjectStreamException; import java.io.ObjectStreamException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Objects; import java.util.Objects;
/** /**
@ -265,25 +262,11 @@ public final class SerializedLambda implements Serializable {
@java.io.Serial @java.io.Serial
private Object readResolve() throws ObjectStreamException { private Object readResolve() throws ObjectStreamException {
try { try {
@SuppressWarnings("removal") Method deserialize = capturingClass.getDeclaredMethod("$deserializeLambda$", SerializedLambda.class);
Method deserialize = AccessController.doPrivileged(new PrivilegedExceptionAction<>() { deserialize.setAccessible(true);
@Override
public Method run() throws Exception {
Method m = capturingClass.getDeclaredMethod("$deserializeLambda$", SerializedLambda.class);
m.setAccessible(true);
return m;
}
});
return deserialize.invoke(null, this); return deserialize.invoke(null, this);
} catch (ReflectiveOperationException roe) { } catch (ReflectiveOperationException roe) {
throw new InvalidObjectException("ReflectiveOperationException during deserialization", roe); throw new InvalidObjectException("ReflectiveOperationException during deserialization", roe);
} catch (PrivilegedActionException e) {
Exception cause = e.getException();
if (cause instanceof RuntimeException re)
throw re;
else
throw new RuntimeException("Exception in SerializedLambda.readResolve", e);
} }
} }

View File

@ -28,15 +28,12 @@ package java.lang.reflect;
import java.lang.annotation.Annotation; import java.lang.annotation.Annotation;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.security.AccessController;
import jdk.internal.access.SharedSecrets; import jdk.internal.access.SharedSecrets;
import jdk.internal.misc.VM; import jdk.internal.misc.VM;
import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection; import jdk.internal.reflect.Reflection;
import jdk.internal.reflect.ReflectionFactory; import jdk.internal.reflect.ReflectionFactory;
import sun.security.action.GetPropertyAction;
import sun.security.util.SecurityConstants;
/** /**
* The {@code AccessibleObject} class is the base class for {@code Field}, * The {@code AccessibleObject} class is the base class for {@code Field},
@ -81,17 +78,6 @@ public class AccessibleObject implements AnnotatedElement {
SharedSecrets.setJavaLangReflectAccess(new ReflectAccess()); SharedSecrets.setJavaLangReflectAccess(new ReflectAccess());
} }
static void checkPermission() {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
// SecurityConstants.ACCESS_PERMISSION is used to check
// whether a client has sufficient privilege to defeat Java
// language access control checks.
sm.checkPermission(SecurityConstants.ACCESS_PERMISSION);
}
}
/** /**
* Convenience method to set the {@code accessible} flag for an * Convenience method to set the {@code accessible} flag for an
* array of reflected objects. * array of reflected objects.
@ -114,7 +100,6 @@ public class AccessibleObject implements AnnotatedElement {
*/ */
@CallerSensitive @CallerSensitive
public static void setAccessible(AccessibleObject[] array, boolean flag) { public static void setAccessible(AccessibleObject[] array, boolean flag) {
checkPermission();
if (flag) { if (flag) {
Class<?> caller = Reflection.getCallerClass(); Class<?> caller = Reflection.getCallerClass();
array = array.clone(); array = array.clone();
@ -196,7 +181,6 @@ public class AccessibleObject implements AnnotatedElement {
*/ */
@CallerSensitive // overrides in Method/Field/Constructor are @CS @CallerSensitive // overrides in Method/Field/Constructor are @CS
public void setAccessible(boolean flag) { public void setAccessible(boolean flag) {
AccessibleObject.checkPermission();
setAccessible0(flag); setAccessible0(flag);
} }
@ -257,8 +241,6 @@ public class AccessibleObject implements AnnotatedElement {
*/ */
@CallerSensitive @CallerSensitive
public final boolean trySetAccessible() { public final boolean trySetAccessible() {
AccessibleObject.checkPermission();
if (override == true) return true; if (override == true) return true;
// if it's not a Constructor, Method, Field then no access check // if it's not a Constructor, Method, Field then no access check
@ -502,10 +484,7 @@ public class AccessibleObject implements AnnotatedElement {
// Reflection factory used by subclasses for creating field, // Reflection factory used by subclasses for creating field,
// method, and constructor accessors. Note that this is called // method, and constructor accessors. Note that this is called
// very early in the bootstrapping process. // very early in the bootstrapping process.
@SuppressWarnings("removal") static final ReflectionFactory reflectionFactory = ReflectionFactory.getReflectionFactory();
static final ReflectionFactory reflectionFactory =
AccessController.doPrivileged(
new ReflectionFactory.GetReflectionFactoryAction());
/** /**
* {@inheritDoc} * {@inheritDoc}
@ -623,8 +602,7 @@ public class AccessibleObject implements AnnotatedElement {
// For non-public members or members in package-private classes, // For non-public members or members in package-private classes,
// it is necessary to perform somewhat expensive access checks. // it is necessary to perform somewhat expensive access checks.
// If the access check succeeds for a given class, it will // If the access check succeeds for a given class, it will
// always succeed (it is not affected by the granting or revoking // always succeed; we speed up the check in the common case by
// of permissions); we speed up the check in the common case by
// remembering the last Class for which the check succeeded. // remembering the last Class for which the check succeeded.
// //
// The simple access check for Constructor is to see if // The simple access check for Constructor is to see if
@ -756,8 +734,7 @@ public class AccessibleObject implements AnnotatedElement {
*/ */
private static boolean printStackTraceWhenAccessFails() { private static boolean printStackTraceWhenAccessFails() {
if (!printStackPropertiesSet && VM.initLevel() >= 1) { if (!printStackPropertiesSet && VM.initLevel() >= 1) {
String s = GetPropertyAction.privilegedGetProperty( String s = System.getProperty("sun.reflect.debugModuleAccessChecks");
"sun.reflect.debugModuleAccessChecks");
if (s != null) { if (s != null) {
printStackWhenAccessFails = !s.equalsIgnoreCase("false"); printStackWhenAccessFails = !s.equalsIgnoreCase("false");
} }

View File

@ -181,7 +181,6 @@ public final class Constructor<T> extends Executable {
@Override @Override
@CallerSensitive @CallerSensitive
public void setAccessible(boolean flag) { public void setAccessible(boolean flag) {
AccessibleObject.checkPermission();
if (flag) { if (flag) {
checkCanSetAccessible(Reflection.getCallerClass()); checkCanSetAccessible(Reflection.getCallerClass());
} }

View File

@ -170,7 +170,6 @@ class Field extends AccessibleObject implements Member {
@Override @Override
@CallerSensitive @CallerSensitive
public void setAccessible(boolean flag) { public void setAccessible(boolean flag) {
AccessibleObject.checkPermission();
if (flag) checkCanSetAccessible(Reflection.getCallerClass()); if (flag) checkCanSetAccessible(Reflection.getCallerClass());
setAccessible0(flag); setAccessible0(flag);
} }
@ -1155,7 +1154,6 @@ class Field extends AccessibleObject implements Member {
modifiers); modifiers);
} }
// security check is done before calling this method
private FieldAccessor getFieldAccessor() { private FieldAccessor getFieldAccessor() {
FieldAccessor a = fieldAccessor; FieldAccessor a = fieldAccessor;
return (a != null) ? a : acquireFieldAccessor(); return (a != null) ? a : acquireFieldAccessor();

View File

@ -173,7 +173,6 @@ public final class Method extends Executable {
@Override @Override
@CallerSensitive @CallerSensitive
public void setAccessible(boolean flag) { public void setAccessible(boolean flag) {
AccessibleObject.checkPermission();
if (flag) checkCanSetAccessible(Reflection.getCallerClass()); if (flag) checkCanSetAccessible(Reflection.getCallerClass());
setAccessible0(flag); setAccessible0(flag);
} }

View File

@ -30,8 +30,6 @@ import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType; import java.lang.invoke.MethodType;
import java.lang.invoke.WrongMethodTypeException; import java.lang.invoke.WrongMethodTypeException;
import java.lang.module.ModuleDescriptor; import java.lang.module.ModuleDescriptor;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
@ -52,13 +50,9 @@ import jdk.internal.access.JavaLangAccess;
import jdk.internal.access.SharedSecrets; import jdk.internal.access.SharedSecrets;
import jdk.internal.module.Modules; import jdk.internal.module.Modules;
import jdk.internal.misc.VM; import jdk.internal.misc.VM;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import jdk.internal.loader.ClassLoaderValue; import jdk.internal.loader.ClassLoaderValue;
import jdk.internal.vm.annotation.Stable; import jdk.internal.vm.annotation.Stable;
import sun.reflect.misc.ReflectUtil; import sun.reflect.misc.ReflectUtil;
import sun.security.action.GetPropertyAction;
import sun.security.util.SecurityConstants;
import static java.lang.invoke.MethodType.methodType; import static java.lang.invoke.MethodType.methodType;
import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC; import static java.lang.module.ModuleDescriptor.Modifier.SYNTHETIC;
@ -366,17 +360,11 @@ public class Proxy implements java.io.Serializable {
* @see <a href="#membership">Package and Module Membership of Proxy Class</a> * @see <a href="#membership">Package and Module Membership of Proxy Class</a>
*/ */
@Deprecated @Deprecated
@CallerSensitive
public static Class<?> getProxyClass(ClassLoader loader, public static Class<?> getProxyClass(ClassLoader loader,
Class<?>... interfaces) Class<?>... interfaces)
throws IllegalArgumentException throws IllegalArgumentException
{ {
@SuppressWarnings("removal") return getProxyConstructor(loader, interfaces)
Class<?> caller = System.getSecurityManager() == null
? null
: Reflection.getCallerClass();
return getProxyConstructor(caller, loader, interfaces)
.getDeclaringClass(); .getDeclaringClass();
} }
@ -386,25 +374,18 @@ public class Proxy implements java.io.Serializable {
* and an array of interfaces. The returned constructor will have the * and an array of interfaces. The returned constructor will have the
* {@link Constructor#setAccessible(boolean) accessible} flag already set. * {@link Constructor#setAccessible(boolean) accessible} flag already set.
* *
* @param caller passed from a public-facing @CallerSensitive method if
* SecurityManager is set or {@code null} if there's no
* SecurityManager
* @param loader the class loader to define the proxy class * @param loader the class loader to define the proxy class
* @param interfaces the list of interfaces for the proxy class * @param interfaces the list of interfaces for the proxy class
* to implement * to implement
* @return a Constructor of the proxy class taking single * @return a Constructor of the proxy class taking single
* {@code InvocationHandler} parameter * {@code InvocationHandler} parameter
*/ */
private static Constructor<?> getProxyConstructor(Class<?> caller, private static Constructor<?> getProxyConstructor(ClassLoader loader,
ClassLoader loader,
Class<?>... interfaces) Class<?>... interfaces)
{ {
// optimization for single interface // optimization for single interface
if (interfaces.length == 1) { if (interfaces.length == 1) {
Class<?> intf = interfaces[0]; Class<?> intf = interfaces[0];
if (caller != null) {
checkProxyAccess(caller, loader, intf);
}
return proxyCache.sub(intf).computeIfAbsent( return proxyCache.sub(intf).computeIfAbsent(
loader, loader,
(ld, clv) -> new ProxyBuilder(ld, clv.key()).build() (ld, clv) -> new ProxyBuilder(ld, clv.key()).build()
@ -412,9 +393,6 @@ public class Proxy implements java.io.Serializable {
} else { } else {
// interfaces cloned // interfaces cloned
final Class<?>[] intfsArray = interfaces.clone(); final Class<?>[] intfsArray = interfaces.clone();
if (caller != null) {
checkProxyAccess(caller, loader, intfsArray);
}
final List<Class<?>> intfs = Arrays.asList(intfsArray); final List<Class<?>> intfs = Arrays.asList(intfsArray);
return proxyCache.sub(intfs).computeIfAbsent( return proxyCache.sub(intfs).computeIfAbsent(
loader, loader,
@ -423,39 +401,6 @@ public class Proxy implements java.io.Serializable {
} }
} }
/*
* Check permissions required to create a Proxy class.
*
* To define a proxy class, it performs the access checks as in
* Class.forName (VM will invoke ClassLoader.checkPackageAccess):
* 1. "getClassLoader" permission check if loader == null
* 2. checkPackageAccess on the interfaces it implements
*
* To get a constructor and new instance of a proxy class, it performs
* the package access check on the interfaces it implements
* as in Class.getConstructor.
*
* If an interface is non-public, the proxy class must be defined by
* the defining loader of the interface. If the caller's class loader
* is not the same as the defining loader of the interface, the VM
* will throw IllegalAccessError when the generated proxy class is
* being defined.
*/
private static void checkProxyAccess(Class<?> caller,
ClassLoader loader,
Class<?> ... interfaces)
{
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader ccl = caller.getClassLoader();
if (loader == null && ccl != null) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
}
ReflectUtil.checkProxyPackageAccess(ccl, interfaces);
}
}
/** /**
* Builder for a proxy class. * Builder for a proxy class.
* *
@ -516,7 +461,7 @@ public class Proxy implements java.io.Serializable {
? proxyClassNamePrefix + num ? proxyClassNamePrefix + num
: context.packageName() + "." + proxyClassNamePrefix + num; : context.packageName() + "." + proxyClassNamePrefix + num;
ClassLoader loader = getLoader(context.module()); ClassLoader loader = context.module().getClassLoader();
trace(proxyName, context.module(), loader, interfaces); trace(proxyName, context.module(), loader, interfaces);
/* /*
@ -586,8 +531,7 @@ public class Proxy implements java.io.Serializable {
} }
} }
private static final String DEBUG = private static final String DEBUG = System.getProperty("jdk.proxy.debug", "");
GetPropertyAction.privilegedGetProperty("jdk.proxy.debug", "");
private static boolean isDebug() { private static boolean isDebug() {
return !DEBUG.isEmpty(); return !DEBUG.isEmpty();
@ -618,7 +562,7 @@ public class Proxy implements java.io.Serializable {
this.interfaces = interfaces; this.interfaces = interfaces;
this.context = proxyClassContext(loader, interfaces, refTypes); this.context = proxyClassContext(loader, interfaces, refTypes);
assert getLoader(context.module()) == loader; assert context.module().getClassLoader() == loader;
} }
ProxyBuilder(ClassLoader loader, Class<?> intf) { ProxyBuilder(ClassLoader loader, Class<?> intf) {
@ -630,11 +574,7 @@ public class Proxy implements java.io.Serializable {
* accessible flag already set. If the target module does not have access * accessible flag already set. If the target module does not have access
* to any interface types, IllegalAccessError will be thrown by the VM * to any interface types, IllegalAccessError will be thrown by the VM
* at defineClass time. * at defineClass time.
*
* Must call the checkProxyAccess method to perform permission checks
* before calling this.
*/ */
@SuppressWarnings("removal")
Constructor<?> build() { Constructor<?> build() {
Class<?> proxyClass = defineProxyClass(context, interfaces); Class<?> proxyClass = defineProxyClass(context, interfaces);
@ -644,12 +584,7 @@ public class Proxy implements java.io.Serializable {
} catch (NoSuchMethodException e) { } catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e); throw new InternalError(e.toString(), e);
} }
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true); cons.setAccessible(true);
return null;
}
});
return cons; return cons;
} }
@ -788,7 +723,7 @@ public class Proxy implements java.io.Serializable {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"cannot have non-public interfaces in different packages"); "cannot have non-public interfaces in different packages");
} }
if (getLoader(m) != loader) { if (m.getClassLoader() != loader) {
// the specified loader is not the same class loader // the specified loader is not the same class loader
// of the non-public interface // of the non-public interface
throw new IllegalArgumentException( throw new IllegalArgumentException(
@ -979,36 +914,24 @@ public class Proxy implements java.io.Serializable {
* *
* @see <a href="#membership">Package and Module Membership of Proxy Class</a> * @see <a href="#membership">Package and Module Membership of Proxy Class</a>
*/ */
@CallerSensitive
public static Object newProxyInstance(ClassLoader loader, public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces, Class<?>[] interfaces,
InvocationHandler h) { InvocationHandler h) {
Objects.requireNonNull(h); Objects.requireNonNull(h);
@SuppressWarnings("removal")
final Class<?> caller = System.getSecurityManager() == null
? null
: Reflection.getCallerClass();
/* /*
* Look up or generate the designated proxy class and its constructor. * Look up or generate the designated proxy class and its constructor.
*/ */
Constructor<?> cons = getProxyConstructor(caller, loader, interfaces); Constructor<?> cons = getProxyConstructor(loader, interfaces);
return newProxyInstance(caller, cons, h); return newProxyInstance(cons, h);
} }
private static Object newProxyInstance(Class<?> caller, // null if no SecurityManager private static Object newProxyInstance(Constructor<?> cons, InvocationHandler h) {
Constructor<?> cons,
InvocationHandler h) {
/* /*
* Invoke its constructor with the designated invocation handler. * Invoke its constructor with the designated invocation handler.
*/ */
try { try {
if (caller != null) {
checkNewProxyPermission(caller, cons.getDeclaringClass());
}
return cons.newInstance(new Object[]{h}); return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException | InstantiationException e) { } catch (IllegalAccessException | InstantiationException e) {
throw new InternalError(e.toString(), e); throw new InternalError(e.toString(), e);
@ -1022,35 +945,6 @@ public class Proxy implements java.io.Serializable {
} }
} }
private static void checkNewProxyPermission(Class<?> caller, Class<?> proxyClass) {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
if (ReflectUtil.isNonPublicProxyClass(proxyClass)) {
ClassLoader ccl = caller.getClassLoader();
ClassLoader pcl = proxyClass.getClassLoader();
// do permission check if the caller is in a different runtime package
// of the proxy class
String pkg = proxyClass.getPackageName();
String callerPkg = caller.getPackageName();
if (pcl != ccl || !pkg.equals(callerPkg)) {
sm.checkPermission(new ReflectPermission("newProxyInPackage." + pkg));
}
}
}
}
/**
* Returns the class loader for the given module.
*/
@SuppressWarnings("removal")
private static ClassLoader getLoader(Module m) {
PrivilegedAction<ClassLoader> pa = m::getClassLoader;
return AccessController.doPrivileged(pa);
}
/** /**
* Returns true if the given class is a proxy class. * Returns true if the given class is a proxy class.
* *
@ -1075,8 +969,6 @@ public class Proxy implements java.io.Serializable {
* @throws IllegalArgumentException if the argument is not a * @throws IllegalArgumentException if the argument is not a
* proxy instance * proxy instance
*/ */
@SuppressWarnings("removal")
@CallerSensitive
public static InvocationHandler getInvocationHandler(Object proxy) public static InvocationHandler getInvocationHandler(Object proxy)
throws IllegalArgumentException throws IllegalArgumentException
{ {
@ -1089,16 +981,6 @@ public class Proxy implements java.io.Serializable {
final Proxy p = (Proxy) proxy; final Proxy p = (Proxy) proxy;
final InvocationHandler ih = p.h; final InvocationHandler ih = p.h;
if (System.getSecurityManager() != null) {
Class<?> ihClass = ih.getClass();
Class<?> caller = Reflection.getCallerClass();
if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(),
ihClass.getClassLoader()))
{
ReflectUtil.checkPackageAccess(ihClass);
}
}
return ih; return ih;
} }
@ -1249,11 +1131,7 @@ public class Proxy implements java.io.Serializable {
* *
* @return a lookup for proxy class of this proxy instance * @return a lookup for proxy class of this proxy instance
*/ */
@SuppressWarnings("removal")
private static MethodHandles.Lookup proxyClassLookup(MethodHandles.Lookup caller, Class<?> proxyClass) { private static MethodHandles.Lookup proxyClassLookup(MethodHandles.Lookup caller, Class<?> proxyClass) {
return AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
public MethodHandles.Lookup run() {
try { try {
Method m = proxyClass.getDeclaredMethod("proxyClassLookup", MethodHandles.Lookup.class); Method m = proxyClass.getDeclaredMethod("proxyClassLookup", MethodHandles.Lookup.class);
m.setAccessible(true); m.setAccessible(true);
@ -1262,8 +1140,6 @@ public class Proxy implements java.io.Serializable {
throw new InternalError(e); throw new InternalError(e);
} }
} }
});
}
/* /*
* Invoke the default method of the given proxy with an explicit caller class. * Invoke the default method of the given proxy with an explicit caller class.

View File

@ -43,7 +43,6 @@ import java.util.Objects;
import jdk.internal.constant.ClassOrInterfaceDescImpl; import jdk.internal.constant.ClassOrInterfaceDescImpl;
import jdk.internal.constant.ConstantUtils; import jdk.internal.constant.ConstantUtils;
import jdk.internal.constant.MethodTypeDescImpl; import jdk.internal.constant.MethodTypeDescImpl;
import sun.security.action.GetBooleanAction;
import static java.lang.classfile.ClassFile.*; import static java.lang.classfile.ClassFile.*;
import java.lang.classfile.attribute.StackMapFrameInfo; import java.lang.classfile.attribute.StackMapFrameInfo;
@ -106,9 +105,8 @@ final class ProxyGenerator {
*/ */
@SuppressWarnings("removal") @SuppressWarnings("removal")
private static final boolean SAVE_GENERATED_FILES = private static final boolean SAVE_GENERATED_FILES =
java.security.AccessController.doPrivileged( Boolean.getBoolean("jdk.proxy.ProxyGenerator.saveGeneratedFiles");
new GetBooleanAction(
"jdk.proxy.ProxyGenerator.saveGeneratedFiles"));
/* Preloaded ProxyMethod objects for methods in java.lang.Object */ /* Preloaded ProxyMethod objects for methods in java.lang.Object */
private static final Method OBJECT_HASH_CODE_METHOD; private static final Method OBJECT_HASH_CODE_METHOD;
@ -215,9 +213,6 @@ final class ProxyGenerator {
final byte[] classFile = gen.generateClassFile(); final byte[] classFile = gen.generateClassFile();
if (SAVE_GENERATED_FILES) { if (SAVE_GENERATED_FILES) {
java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<Void>() {
public Void run() {
try { try {
int i = name.lastIndexOf('.'); int i = name.lastIndexOf('.');
Path path; Path path;
@ -231,12 +226,9 @@ final class ProxyGenerator {
Files.write(path, classFile); Files.write(path, classFile);
return null; return null;
} catch (IOException e) { } catch (IOException e) {
throw new InternalError( throw new InternalError("I/O exception saving generated file: " + e);
"I/O exception saving generated file: " + e);
} }
} }
});
}
return classFile; return classFile;
} }
@ -565,11 +557,6 @@ final class ProxyGenerator {
/** /**
* Generate the class initializer. * Generate the class initializer.
* Discussion: Currently, for Proxy to work with SecurityManager,
* we rely on the parameter classes of the methods to be computed
* from Proxy instead of via user code paths like bootstrap method
* lazy evaluation. That might change if we can pass in the live
* Method objects directly..
*/ */
private void generateStaticInitializer(ClassBuilder clb) { private void generateStaticInitializer(ClassBuilder clb) {
clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> { clb.withMethodBody(CLASS_INIT_NAME, MTD_void, ACC_STATIC, cob -> {
@ -786,9 +773,6 @@ final class ProxyGenerator {
* Generate code for initializing the static field that stores * Generate code for initializing the static field that stores
* the Method object for this proxy method. A class loader is * the Method object for this proxy method. A class loader is
* anticipated at local variable index 0. * anticipated at local variable index 0.
* The generated code must be run in an AccessController.doPrivileged
* block if a SecurityManager is present, as otherwise the code
* cannot pass {@code null} ClassLoader to forName.
*/ */
private void codeFieldInitialization(CodeBuilder cob) { private void codeFieldInitialization(CodeBuilder cob) {
var cp = cob.constantPool(); var cp = cob.constantPool();

View File

@ -35,11 +35,6 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.net.URL; import java.net.URL;
import java.net.URLConnection; import java.net.URLConnection;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -396,10 +391,6 @@ public final class ServiceLoader<S>
// null when locating provider using a module layer // null when locating provider using a module layer
private final ClassLoader loader; private final ClassLoader loader;
// The access control context taken when the ServiceLoader is created
@SuppressWarnings("removal")
private final AccessControlContext acc;
// The lazy-lookup iterator for iterator operations // The lazy-lookup iterator for iterator operations
private Iterator<Provider<S>> lookupIterator1; private Iterator<Provider<S>> lookupIterator1;
private final List<S> instantiatedProviders = new ArrayList<>(); private final List<S> instantiatedProviders = new ArrayList<>();
@ -462,7 +453,6 @@ public final class ServiceLoader<S>
* If {@code svc} is not accessible to {@code caller} or the caller * If {@code svc} is not accessible to {@code caller} or the caller
* module does not use the service type. * module does not use the service type.
*/ */
@SuppressWarnings("removal")
private ServiceLoader(Class<?> caller, ModuleLayer layer, Class<S> svc) { private ServiceLoader(Class<?> caller, ModuleLayer layer, Class<S> svc) {
Objects.requireNonNull(caller); Objects.requireNonNull(caller);
Objects.requireNonNull(layer); Objects.requireNonNull(layer);
@ -473,9 +463,6 @@ public final class ServiceLoader<S>
this.serviceName = svc.getName(); this.serviceName = svc.getName();
this.layer = layer; this.layer = layer;
this.loader = null; this.loader = null;
this.acc = (System.getSecurityManager() != null)
? AccessController.getContext()
: null;
} }
/** /**
@ -486,7 +473,6 @@ public final class ServiceLoader<S>
* If {@code svc} is not accessible to {@code caller} or the caller * If {@code svc} is not accessible to {@code caller} or the caller
* module does not use the service type. * module does not use the service type.
*/ */
@SuppressWarnings("removal")
private ServiceLoader(Class<?> caller, Class<S> svc, ClassLoader cl) { private ServiceLoader(Class<?> caller, Class<S> svc, ClassLoader cl) {
Objects.requireNonNull(svc); Objects.requireNonNull(svc);
@ -515,9 +501,6 @@ public final class ServiceLoader<S>
this.serviceName = svc.getName(); this.serviceName = svc.getName();
this.layer = null; this.layer = null;
this.loader = cl; this.loader = cl;
this.acc = (System.getSecurityManager() != null)
? AccessController.getContext()
: null;
} }
/** /**
@ -529,7 +512,6 @@ public final class ServiceLoader<S>
* @throws ServiceConfigurationError * @throws ServiceConfigurationError
* If the caller module does not use the service type. * If the caller module does not use the service type.
*/ */
@SuppressWarnings("removal")
private ServiceLoader(Module callerModule, Class<S> svc, ClassLoader cl) { private ServiceLoader(Module callerModule, Class<S> svc, ClassLoader cl) {
if (!callerModule.canUse(svc)) { if (!callerModule.canUse(svc)) {
fail(svc, callerModule + " does not declare `uses`"); fail(svc, callerModule + " does not declare `uses`");
@ -539,9 +521,6 @@ public final class ServiceLoader<S>
this.serviceName = svc.getName(); this.serviceName = svc.getName();
this.layer = null; this.layer = null;
this.loader = cl; this.loader = cl;
this.acc = (System.getSecurityManager() != null)
? AccessController.getContext()
: null;
} }
/** /**
@ -601,7 +580,6 @@ public final class ServiceLoader<S>
* provider method or there is more than one public static * provider method or there is more than one public static
* provider method * provider method
*/ */
@SuppressWarnings("removal")
private Method findStaticProviderMethod(Class<?> clazz) { private Method findStaticProviderMethod(Class<?> clazz) {
List<Method> methods = null; List<Method> methods = null;
try { try {
@ -628,12 +606,7 @@ public final class ServiceLoader<S>
} }
} }
if (result != null) { if (result != null) {
Method m = result; result.setAccessible(true);
PrivilegedAction<Void> pa = () -> {
m.setAccessible(true);
return null;
};
AccessController.doPrivileged(pa);
} }
return result; return result;
} }
@ -644,27 +617,16 @@ public final class ServiceLoader<S>
* @throws ServiceConfigurationError if the class does not have * @throws ServiceConfigurationError if the class does not have
* public no-arg constructor * public no-arg constructor
*/ */
@SuppressWarnings("removal")
private Constructor<?> getConstructor(Class<?> clazz) { private Constructor<?> getConstructor(Class<?> clazz) {
PrivilegedExceptionAction<Constructor<?>> pa
= new PrivilegedExceptionAction<>() {
@Override
public Constructor<?> run() throws Exception {
Constructor<?> ctor = clazz.getConstructor();
if (inExplicitModule(clazz))
ctor.setAccessible(true);
return ctor;
}
};
Constructor<?> ctor = null; Constructor<?> ctor = null;
try { try {
ctor = AccessController.doPrivileged(pa); ctor = clazz.getConstructor();
} catch (Throwable x) { } catch (NoSuchMethodException ex) {
if (x instanceof PrivilegedActionException)
x = x.getCause();
String cn = clazz.getName(); String cn = clazz.getName();
fail(service, cn + " Unable to get public no-arg constructor", x); fail(service, cn + " Unable to get public no-arg constructor", ex);
} }
if (inExplicitModule(clazz))
ctor.setAccessible(true);
return ctor; return ctor;
} }
@ -678,29 +640,23 @@ public final class ServiceLoader<S>
final Class<? extends S> type; final Class<? extends S> type;
final Method factoryMethod; // factory method or null final Method factoryMethod; // factory method or null
final Constructor<? extends S> ctor; // public no-args constructor or null final Constructor<? extends S> ctor; // public no-args constructor or null
@SuppressWarnings("removal")
final AccessControlContext acc;
ProviderImpl(Class<S> service, ProviderImpl(Class<S> service,
Class<? extends S> type, Class<? extends S> type,
Method factoryMethod, Method factoryMethod) {
@SuppressWarnings("removal") AccessControlContext acc) {
this.service = service; this.service = service;
this.type = type; this.type = type;
this.factoryMethod = factoryMethod; this.factoryMethod = factoryMethod;
this.ctor = null; this.ctor = null;
this.acc = acc;
} }
ProviderImpl(Class<S> service, ProviderImpl(Class<S> service,
Class<? extends S> type, Class<? extends S> type,
Constructor<? extends S> ctor, Constructor<? extends S> ctor) {
@SuppressWarnings("removal") AccessControlContext acc) {
this.service = service; this.service = service;
this.type = type; this.type = type;
this.factoryMethod = null; this.factoryMethod = null;
this.ctor = ctor; this.ctor = ctor;
this.acc = acc;
} }
@Override @Override
@ -723,36 +679,14 @@ public final class ServiceLoader<S>
* permissions that are restricted by the security context of whatever * permissions that are restricted by the security context of whatever
* created this loader. * created this loader.
*/ */
@SuppressWarnings("removal")
private S invokeFactoryMethod() { private S invokeFactoryMethod() {
Object result = null; Object result = null;
Throwable exc = null;
if (acc == null) {
try { try {
result = factoryMethod.invoke(null); result = factoryMethod.invoke(null);
} catch (Throwable x) { } catch (Throwable ex) {
exc = x; if (ex instanceof InvocationTargetException)
} ex = ex.getCause();
} else { fail(service, factoryMethod + " failed", ex);
PrivilegedExceptionAction<?> pa = new PrivilegedExceptionAction<>() {
@Override
public Object run() throws Exception {
return factoryMethod.invoke(null);
}
};
// invoke factory method with permissions restricted by acc
try {
result = AccessController.doPrivileged(pa, acc);
} catch (Throwable x) {
if (x instanceof PrivilegedActionException)
x = x.getCause();
exc = x;
}
}
if (exc != null) {
if (exc instanceof InvocationTargetException)
exc = exc.getCause();
fail(service, factoryMethod + " failed", exc);
} }
if (result == null) { if (result == null) {
fail(service, factoryMethod + " returned null"); fail(service, factoryMethod + " returned null");
@ -767,38 +701,16 @@ public final class ServiceLoader<S>
* with a security manager then the constructor runs with permissions that * with a security manager then the constructor runs with permissions that
* are restricted by the security context of whatever created this loader. * are restricted by the security context of whatever created this loader.
*/ */
@SuppressWarnings("removal")
private S newInstance() { private S newInstance() {
S p = null; S p = null;
Throwable exc = null;
if (acc == null) {
try { try {
p = ctor.newInstance(); p = ctor.newInstance();
} catch (Throwable x) { } catch (Throwable ex) {
exc = x; if (ex instanceof InvocationTargetException)
} ex = ex.getCause();
} else {
PrivilegedExceptionAction<S> pa = new PrivilegedExceptionAction<>() {
@Override
public S run() throws Exception {
return ctor.newInstance();
}
};
// invoke constructor with permissions restricted by acc
try {
p = AccessController.doPrivileged(pa, acc);
} catch (Throwable x) {
if (x instanceof PrivilegedActionException)
x = x.getCause();
exc = x;
}
}
if (exc != null) {
if (exc instanceof InvocationTargetException)
exc = exc.getCause();
String cn = ctor.getDeclaringClass().getName(); String cn = ctor.getDeclaringClass().getName();
fail(service, fail(service,
"Provider " + cn + " could not be instantiated", exc); "Provider " + cn + " could not be instantiated", ex);
} }
return p; return p;
} }
@ -809,15 +721,14 @@ public final class ServiceLoader<S>
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(service, type, acc); return Objects.hash(service, type);
} }
@Override @Override
public boolean equals(Object ob) { public boolean equals(Object ob) {
return ob instanceof @SuppressWarnings("unchecked")ProviderImpl<?> that return ob instanceof @SuppressWarnings("unchecked")ProviderImpl<?> that
&& this.service == that.service && this.service == that.service
&& this.type == that.type && this.type == that.type;
&& Objects.equals(this.acc, that.acc);
} }
} }
@ -831,7 +742,6 @@ public final class ServiceLoader<S>
* isn't the expected sub-type (or doesn't define a provider * isn't the expected sub-type (or doesn't define a provider
* factory method that returns the expected type) * factory method that returns the expected type)
*/ */
@SuppressWarnings("removal")
private Provider<S> loadProvider(ServiceProvider provider) { private Provider<S> loadProvider(ServiceProvider provider) {
Module module = provider.module(); Module module = provider.module();
if (!module.canRead(service.getModule())) { if (!module.canRead(service.getModule())) {
@ -841,23 +751,11 @@ public final class ServiceLoader<S>
String cn = provider.providerName(); String cn = provider.providerName();
Class<?> clazz = null; Class<?> clazz = null;
if (acc == null) {
try { try {
clazz = Class.forName(module, cn); clazz = Class.forName(module, cn);
} catch (LinkageError e) { } catch (LinkageError e) {
fail(service, "Unable to load " + cn, e); fail(service, "Unable to load " + cn, e);
} }
} else {
PrivilegedExceptionAction<Class<?>> pa = () -> Class.forName(module, cn);
try {
clazz = AccessController.doPrivileged(pa);
} catch (Throwable x) {
if (x instanceof PrivilegedActionException)
x = x.getCause();
fail(service, "Unable to load " + cn, x);
return null;
}
}
if (clazz == null) { if (clazz == null) {
fail(service, "Provider " + cn + " not found"); fail(service, "Provider " + cn + " not found");
} }
@ -878,7 +776,7 @@ public final class ServiceLoader<S>
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Class<? extends S> type = (Class<? extends S>) returnType; Class<? extends S> type = (Class<? extends S>) returnType;
return new ProviderImpl<S>(service, type, factoryMethod, acc); return new ProviderImpl<S>(service, type, factoryMethod);
} }
} }
@ -891,7 +789,7 @@ public final class ServiceLoader<S>
Class<? extends S> type = (Class<? extends S>) clazz; Class<? extends S> type = (Class<? extends S>) clazz;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Constructor<? extends S> ctor = (Constructor<? extends S> ) getConstructor(clazz); Constructor<? extends S> ctor = (Constructor<? extends S> ) getConstructor(clazz);
return new ProviderImpl<S>(service, type, ctor, acc); return new ProviderImpl<S>(service, type, ctor);
} }
/** /**
@ -997,20 +895,6 @@ public final class ServiceLoader<S>
return catalog.findServices(serviceName); return catalog.findServices(serviceName);
} }
/**
* Returns the class loader that a module is defined to
*/
@SuppressWarnings("removal")
private ClassLoader loaderFor(Module module) {
SecurityManager sm = System.getSecurityManager();
if (sm == null) {
return module.getClassLoader();
} else {
PrivilegedAction<ClassLoader> pa = module::getClassLoader;
return AccessController.doPrivileged(pa);
}
}
/** /**
* Returns an iterator to iterate over the implementations of {@code * Returns an iterator to iterate over the implementations of {@code
* service} in modules defined to the given class loader or in custom * service} in modules defined to the given class loader or in custom
@ -1041,7 +925,7 @@ public final class ServiceLoader<S>
while (iterator.hasNext()) { while (iterator.hasNext()) {
ModuleLayer layer = iterator.next(); ModuleLayer layer = iterator.next();
for (ServiceProvider sp : providers(layer)) { for (ServiceProvider sp : providers(layer)) {
ClassLoader l = loaderFor(sp.module()); ClassLoader l = sp.module().getClassLoader();
if (l != null && l != platformClassLoader) { if (l != null && l != platformClassLoader) {
allProviders.add(sp); allProviders.add(sp);
} }
@ -1225,7 +1109,7 @@ public final class ServiceLoader<S>
Class<? extends S> type = (Class<? extends S>) clazz; Class<? extends S> type = (Class<? extends S>) clazz;
Constructor<? extends S> ctor Constructor<? extends S> ctor
= (Constructor<? extends S>)getConstructor(clazz); = (Constructor<? extends S>)getConstructor(clazz);
ProviderImpl<S> p = new ProviderImpl<S>(service, type, ctor, acc); ProviderImpl<S> p = new ProviderImpl<S>(service, type, ctor);
nextProvider = (ProviderImpl<T>) p; nextProvider = (ProviderImpl<T>) p;
} else { } else {
fail(service, clazz.getName() + " not a subtype"); fail(service, clazz.getName() + " not a subtype");
@ -1253,30 +1137,14 @@ public final class ServiceLoader<S>
} }
} }
@SuppressWarnings("removal")
@Override @Override
public boolean hasNext() { public boolean hasNext() {
if (acc == null) {
return hasNextService(); return hasNextService();
} else {
PrivilegedAction<Boolean> action = new PrivilegedAction<>() {
public Boolean run() { return hasNextService(); }
};
return AccessController.doPrivileged(action, acc);
}
} }
@SuppressWarnings("removal")
@Override @Override
public Provider<T> next() { public Provider<T> next() {
if (acc == null) {
return nextService(); return nextService();
} else {
PrivilegedAction<Provider<T>> action = new PrivilegedAction<>() {
public Provider<T> run() { return nextService(); }
};
return AccessController.doPrivileged(action, acc);
}
} }
} }

View File

@ -32,8 +32,6 @@ import java.lang.constant.ConstantDescs;
import java.lang.constant.MethodTypeDesc; import java.lang.constant.MethodTypeDesc;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType; import java.lang.invoke.MethodType;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -320,15 +318,8 @@ public final class MethodTypeDescImpl implements MethodTypeDesc {
public MethodType resolveConstantDesc(MethodHandles.Lookup lookup) throws ReflectiveOperationException { public MethodType resolveConstantDesc(MethodHandles.Lookup lookup) throws ReflectiveOperationException {
MethodType mtype; MethodType mtype;
try { try {
@SuppressWarnings("removal") mtype = MethodType.fromMethodDescriptorString(descriptorString(),
MethodType mt = AccessController.doPrivileged(new PrivilegedAction<>() {
@Override
public MethodType run() {
return MethodType.fromMethodDescriptorString(descriptorString(),
lookup.lookupClass().getClassLoader()); lookup.lookupClass().getClassLoader());
}
});
mtype = mt;
} catch (TypeNotPresentException ex) { } catch (TypeNotPresentException ex) {
throw (ClassNotFoundException) ex.getCause(); throw (ClassNotFoundException) ex.getCause();
} }

View File

@ -40,13 +40,10 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.security.PrivilegedAction; import java.security.PrivilegedAction;
import java.util.Properties;
import jdk.internal.access.JavaLangReflectAccess; import jdk.internal.access.JavaLangReflectAccess;
import jdk.internal.access.SharedSecrets; import jdk.internal.access.SharedSecrets;
import jdk.internal.misc.VM; import jdk.internal.misc.VM;
import jdk.internal.vm.annotation.Stable; import jdk.internal.vm.annotation.Stable;
import sun.security.action.GetPropertyAction;
import sun.security.util.SecurityConstants;
/** <P> The master factory for all reflective objects, both those in /** <P> The master factory for all reflective objects, both those in
java.lang.reflect (Fields, Methods, Constructors) as well as their java.lang.reflect (Fields, Methods, Constructors) as well as their
@ -93,27 +90,12 @@ public class ReflectionFactory {
* Provides the caller with the capability to instantiate reflective * Provides the caller with the capability to instantiate reflective
* objects. * objects.
* *
* <p> First, if there is a security manager, its
* <code>checkPermission</code> method is called with a {@link
* java.lang.RuntimePermission} with target
* <code>"reflectionFactoryAccess"</code>. This may result in a
* security exception.
*
* <p> The returned <code>ReflectionFactory</code> object should be * <p> The returned <code>ReflectionFactory</code> object should be
* carefully guarded by the caller, since it can be used to read and * carefully guarded by the caller, since it can be used to read and
* write private data and invoke private methods, as well as to load * write private data and invoke private methods, as well as to load
* unverified bytecodes. It must never be passed to untrusted code. * unverified bytecodes. It must never be passed to untrusted code.
* */
* @exception SecurityException if a security manager exists and its
* <code>checkPermission</code> method doesn't allow
* access to the RuntimePermission "reflectionFactoryAccess". */
public static ReflectionFactory getReflectionFactory() { public static ReflectionFactory getReflectionFactory() {
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(
SecurityConstants.REFLECTION_FACTORY_ACCESS_PERMISSION);
}
return soleInstance; return soleInstance;
} }
@ -549,11 +531,10 @@ public class ReflectionFactory {
private static Config loadConfig() { private static Config loadConfig() {
assert VM.isModuleSystemInited(); assert VM.isModuleSystemInited();
Properties props = GetPropertyAction.privilegedGetProperties();
boolean useNativeAccessorOnly = boolean useNativeAccessorOnly =
"true".equals(props.getProperty("jdk.reflect.useNativeAccessorOnly")); "true".equals(System.getProperty("jdk.reflect.useNativeAccessorOnly"));
boolean disableSerialConstructorChecks = boolean disableSerialConstructorChecks =
"true".equals(props.getProperty("jdk.disableSerialConstructorChecks")); "true".equals(System.getProperty("jdk.disableSerialConstructorChecks"));
return new Config(useNativeAccessorOnly, disableSerialConstructorChecks); return new Config(useNativeAccessorOnly, disableSerialConstructorChecks);
} }

View File

@ -311,8 +311,6 @@ public class VerifyAccess {
// will use the result cached in the JVM system dictionary. Note that the JVM system dictionary // will use the result cached in the JVM system dictionary. Note that the JVM system dictionary
// will record the first successful result. Unsuccessful results are not stored. // will record the first successful result. Unsuccessful results are not stored.
// //
// We use doPrivileged in order to allow an unprivileged caller to ask an arbitrary
// class loader about the binding of the proposed name (type.getName()).
// The looked up type ("res") is compared for equality against the proposed // The looked up type ("res") is compared for equality against the proposed
// type ("type") and then is discarded. Thus, the worst that can happen to // type ("type") and then is discarded. Thus, the worst that can happen to
// the "child" class loader is that it is bothered to load and report a class // the "child" class loader is that it is bothered to load and report a class
@ -320,17 +318,12 @@ public class VerifyAccess {
// memoization. And the caller never gets to look at the alternate type binding // memoization. And the caller never gets to look at the alternate type binding
// ("res"), whether it exists or not. // ("res"), whether it exists or not.
final String name = type.getName(); final String name = type.getName();
@SuppressWarnings("removal") Class<?> res = null;
Class<?> res = java.security.AccessController.doPrivileged(
new java.security.PrivilegedAction<>() {
public Class<?> run() {
try { try {
return Class.forName(name, false, refcLoader); res = Class.forName(name, false, refcLoader);
} catch (ClassNotFoundException | LinkageError e) { } catch (ClassNotFoundException | LinkageError e) {
return null; // Assume the class is not found // Assume the class is not found
} }
}
});
return (type == res); return (type == res);
} }

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 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
@ -23,7 +23,6 @@
* questions. * questions.
*/ */
package sun.reflect.misc; package sun.reflect.misc;
import java.lang.reflect.Member; import java.lang.reflect.Member;
@ -31,16 +30,13 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import jdk.internal.reflect.Reflection; import jdk.internal.reflect.Reflection;
import sun.security.util.SecurityConstants;
public final class ReflectUtil { public final class ReflectUtil {
private ReflectUtil() { private ReflectUtil() {
} }
public static Class<?> forName(String name) public static Class<?> forName(String name) throws ClassNotFoundException {
throws ClassNotFoundException {
checkPackageAccess(name);
return Class.forName(name); return Class.forName(name);
} }
@ -73,182 +69,48 @@ public final class ReflectUtil {
} }
/** /**
* Does a conservative approximation of member access check. Use this if * Does nothing.
* you don't have an actual 'userland' caller Class/ClassLoader available.
* This might be more restrictive than a precise member access check where
* you have a caller, but should never allow a member access that is
* forbidden.
*
* @param m the {@code Member} about to be accessed
*/ */
public static void conservativeCheckMemberAccess(Member m) throws SecurityException{ public static void conservativeCheckMemberAccess(Member m) {
@SuppressWarnings("removal")
final SecurityManager sm = System.getSecurityManager();
if (sm == null)
return;
// Check for package access on the declaring class.
//
// In addition, unless the member and the declaring class are both
// public check for access declared member permissions.
//
// This is done regardless of ClassLoader relations between the {@code
// Member m} and any potential caller.
final Class<?> declaringClass = m.getDeclaringClass();
privateCheckPackageAccess(sm, declaringClass);
if (Modifier.isPublic(m.getModifiers()) &&
Modifier.isPublic(declaringClass.getModifiers()))
return;
// Check for declared member access.
sm.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
} }
/** /**
* Checks package access on the given class. * Does nothing.
*
* If it is a {@link Proxy#isProxyClass(java.lang.Class)} that implements
* a non-public interface (i.e. may be in a non-restricted package),
* also check the package access on the proxy interfaces.
*/ */
public static void checkPackageAccess(Class<?> clazz) { public static void checkPackageAccess(Class<?> clazz) {
@SuppressWarnings("removal")
SecurityManager s = System.getSecurityManager();
if (s != null) {
privateCheckPackageAccess(s, clazz);
}
} }
/** /**
* NOTE: should only be called if a SecurityManager is installed * Does nothing
*/
private static void privateCheckPackageAccess(@SuppressWarnings("removal") SecurityManager s, Class<?> clazz) {
String pkg = clazz.getPackageName();
if (!pkg.isEmpty()) {
s.checkPackageAccess(pkg);
}
if (isNonPublicProxyClass(clazz)) {
privateCheckProxyPackageAccess(s, clazz);
}
}
/**
* Checks package access on the given classname.
* This method is typically called when the Class instance is not
* available and the caller attempts to load a class on behalf
* the true caller (application).
*/ */
public static void checkPackageAccess(String name) { public static void checkPackageAccess(String name) {
@SuppressWarnings("removal")
SecurityManager s = System.getSecurityManager();
if (s != null) {
String cname = name.replace('/', '.');
if (cname.startsWith("[")) {
int b = cname.lastIndexOf('[') + 2;
if (b > 1 && b < cname.length()) {
cname = cname.substring(b);
}
}
int i = cname.lastIndexOf('.');
if (i != -1) {
s.checkPackageAccess(cname.substring(0, i));
}
}
}
public static boolean isPackageAccessible(Class<?> clazz) {
try {
checkPackageAccess(clazz);
} catch (SecurityException e) {
return false;
}
return true;
}
// Returns true if p is an ancestor of cl i.e. class loader 'p' can
// be found in the cl's delegation chain
private static boolean isAncestor(ClassLoader p, ClassLoader cl) {
ClassLoader acl = cl;
do {
acl = acl.getParent();
if (p == acl) {
return true;
}
} while (acl != null);
return false;
} }
/** /**
* Returns true if package access check is needed for reflective * Returns true.
* access from a class loader 'from' to classes or members in */
* a class defined by class loader 'to'. This method returns true public static boolean isPackageAccessible(Class<?> clazz) {
* if 'from' is not the same as or an ancestor of 'to'. All code return true;
* in a system domain are granted with all permission and so this }
* method returns false if 'from' class loader is a class loader
* loading system classes. On the other hand, if a class loader /**
* attempts to access system domain classes, it requires package * Returns false.
* access check and this method will return true.
*/ */
public static boolean needsPackageAccessCheck(ClassLoader from, ClassLoader to) { public static boolean needsPackageAccessCheck(ClassLoader from, ClassLoader to) {
if (from == null || from == to)
return false; return false;
if (to == null)
return true;
return !isAncestor(from, to);
} }
/** /**
* Check package access on the proxy interfaces that the given proxy class * Does nothing
* implements.
*
* @param clazz Proxy class object
*/ */
public static void checkProxyPackageAccess(Class<?> clazz) { public static void checkProxyPackageAccess(Class<?> clazz) {
@SuppressWarnings("removal")
SecurityManager s = System.getSecurityManager();
if (s != null) {
privateCheckProxyPackageAccess(s, clazz);
}
} }
/** /**
* NOTE: should only be called if a SecurityManager is installed * Does nothing.
*/
private static void privateCheckProxyPackageAccess(@SuppressWarnings("removal") SecurityManager s, Class<?> clazz) {
// check proxy interfaces if the given class is a proxy class
if (Proxy.isProxyClass(clazz)) {
for (Class<?> intf : clazz.getInterfaces()) {
privateCheckPackageAccess(s, intf);
}
}
}
/**
* Access check on the interfaces that a proxy class implements and throw
* {@code SecurityException} if it accesses a restricted package from
* the caller's class loader.
*
* @param ccl the caller's class loader
* @param interfaces the list of interfaces that a proxy class implements
*/ */
public static void checkProxyPackageAccess(ClassLoader ccl, public static void checkProxyPackageAccess(ClassLoader ccl,
Class<?>... interfaces) Class<?>... interfaces) {
{
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
for (Class<?> intf : interfaces) {
ClassLoader cl = intf.getClassLoader();
if (needsPackageAccessCheck(ccl, cl)) {
privateCheckPackageAccess(sm, intf);
}
}
}
} }
// Note that bytecode instrumentation tools may exclude 'sun.*' // Note that bytecode instrumentation tools may exclude 'sun.*'

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2020, 2023, 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
@ -53,7 +53,7 @@ public class StaticArchiveWithLambda {
"-Xlog:class+load,cds") "-Xlog:class+load,cds")
.setArchiveName(archiveName); .setArchiveName(archiveName);
CDSTestUtils.createArchiveAndCheck(opts) CDSTestUtils.createArchiveAndCheck(opts)
.shouldContain("Skipping java/lang/invoke/BoundMethodHandle$Species_LLLL because it is dynamically generated"); .shouldHaveExitValue(0);
// run with archive // run with archive
CDSOptions runOpts = (new CDSOptions()) CDSOptions runOpts = (new CDSOptions())