Skip to content

Commit

Permalink
8342997: Remove use of System::getSecurityManager and SecurityManager…
Browse files Browse the repository at this point in the history
… from JavaFX

8342998: Remove all uses of AccessControlException
8342994: Remove security manager calls in com.sun.javafx.reflect

Reviewed-by: angorya, lkostyra
  • Loading branch information
kevinrushforth committed Nov 14, 2024
1 parent b0e763c commit dd60065
Show file tree
Hide file tree
Showing 33 changed files with 45 additions and 901 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,13 @@

import com.sun.javafx.SecurityUtil;
import java.security.AllPermission;
import java.security.AccessController;
import java.security.PermissionCollection;
import java.security.SecureClassLoader;
import java.security.CodeSource;
import java.io.InputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;


class Trampoline {
Expand All @@ -53,13 +48,11 @@ class Trampoline {
}
}

@SuppressWarnings("removal")
private static void ensureInvocableMethod(Method m)
throws InvocationTargetException
{
Class<?> clazz = m.getDeclaringClass();
if (clazz.equals(AccessController.class) ||
clazz.equals(Method.class) ||
if (clazz.equals(Method.class) ||
clazz.getName().startsWith("java.lang.invoke."))
throw new InvocationTargetException(
new UnsupportedOperationException("invocation not supported"));
Expand Down Expand Up @@ -102,163 +95,6 @@ public static Method[] getMethods(Class<?> cls) {
return cls.getMethods();
}

/*
* Discover the public methods on public classes
* and interfaces accessible to any caller by calling
* Class.getMethods() and walking towards Object until
* we're done.
*/
/*public*/
@SuppressWarnings("removal")
static Method[] getPublicMethods(Class<?> cls) {
// compatibility for update release
if (System.getSecurityManager() == null) {
return cls.getMethods();
}
Map<Signature, Method> sigs = new HashMap<>();
while (cls != null) {
boolean done = getInternalPublicMethods(cls, sigs);
if (done) {
break;
}
getInterfaceMethods(cls, sigs);
cls = cls.getSuperclass();
}
return sigs.values().toArray(new Method[sigs.size()]);
}

/*
* Process the immediate interfaces of this class or interface.
*/
private static void getInterfaceMethods(Class<?> cls,
Map<Signature, Method> sigs) {
Class<?>[] intfs = cls.getInterfaces();
for (int i=0; i < intfs.length; i++) {
Class<?> intf = intfs[i];
boolean done = getInternalPublicMethods(intf, sigs);
if (!done) {
getInterfaceMethods(intf, sigs);
}
}
}

/*
*
* Process the methods in this class or interface
*/
private static boolean getInternalPublicMethods(Class<?> cls,
Map<Signature, Method> sigs) {
Method[] methods = null;
try {
/*
* This class or interface is non-public so we
* can't use any of it's methods. Go back and
* try again with a superclass or superinterface.
*/
if (!Modifier.isPublic(cls.getModifiers())) {
return false;
}
if (!ReflectUtil.isPackageAccessible(cls)) {
return false;
}

methods = cls.getMethods();
} catch (SecurityException se) {
return false;
}

/*
* Check for inherited methods with non-public
* declaring classes. They might override and hide
* methods from their superclasses or
* superinterfaces.
*/
boolean done = true;
for (int i=0; i < methods.length; i++) {
Class<?> dc = methods[i].getDeclaringClass();
if (!Modifier.isPublic(dc.getModifiers())) {
done = false;
break;
}
}

if (done) {
/*
* We're done. Spray all the methods into
* the list and then we're out of here.
*/
for (int i=0; i < methods.length; i++) {
addMethod(sigs, methods[i]);
}
} else {
/*
* Simulate cls.getDeclaredMethods() by
* stripping away inherited methods.
*/
for (int i=0; i < methods.length; i++) {
Class<?> dc = methods[i].getDeclaringClass();
if (cls.equals(dc)) {
addMethod(sigs, methods[i]);
}
}
}
return done;
}

private static void addMethod(Map<Signature, Method> sigs, Method method) {
Signature signature = new Signature(method);
if (!sigs.containsKey(signature)) {
sigs.put(signature, method);
} else if (!method.getDeclaringClass().isInterface()){
/*
* Superclasses beat interfaces.
*/
Method old = sigs.get(signature);
if (old.getDeclaringClass().isInterface()) {
sigs.put(signature, method);
}
}
}

/**
* A class that represents the unique elements of a method that will be a
* key in the method cache.
*/
private static class Signature {
private final String methodName;
private final Class<?>[] argClasses;
private final int hashCode;

Signature(Method m) {
this.methodName = m.getName();
this.argClasses = m.getParameterTypes();
this.hashCode = methodName.hashCode() + Arrays.hashCode(argClasses);
}

@Override public int hashCode() {
return hashCode;
}

@Override public boolean equals(Object o2) {
if (this == o2) {
return true;
}
Signature that = (Signature)o2;
if (!(methodName.equals(that.methodName))) {
return false;
}
if (argClasses.length != that.argClasses.length) {
return false;
}
for (int i = 0; i < argClasses.length; i++) {
if (!(argClasses[i] == that.argClasses[i])) {
return false;
}
}
return true;
}
}


/*
* Get the (unnamed) module of the trampoline class
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,6 @@ private ReflectUtil() {
* also check the package access on the proxy interfaces.
*/
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
*/
private static void privateCheckPackageAccess(@SuppressWarnings("removal") SecurityManager s, Class<?> clazz) {
while (clazz.isArray()) {
clazz = clazz.getComponentType();
}

String pkg = clazz.getPackageName();
if (pkg != null && !pkg.isEmpty()) {
s.checkPackageAccess(pkg);
}

if (isNonPublicProxyClass(clazz)) {
privateCheckProxyPackageAccess(s, clazz);
}
}

/**
Expand All @@ -79,58 +56,9 @@ private static void privateCheckPackageAccess(@SuppressWarnings("removal") Secur
* the true caller (application).
*/
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;
}

/**
* NOTE: should only be called if a SecurityManager is installed
*/
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);
}
}
}

// Note that bytecode instrumentation tools may exclude 'sun.*'
// classes but not generated proxy classes and so keep it in com.sun.*
public static final String PROXY_PACKAGE = "com.sun.proxy";

/**
* Test if the given class is a proxy class that implements
* non-public interface. Such proxy class may be in a non-restricted
* package that bypasses checkPackageAccess.
*/
public static boolean isNonPublicProxyClass(Class<?> cls) {
if (!Proxy.isProxyClass(cls)) {
return false;
}
String pkg = cls.getPackageName();
return pkg == null || !pkg.startsWith(PROXY_PACKAGE);
}
}
Loading

1 comment on commit dd60065

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.