Skip to content

Commit 51f3d85

Browse files
committed
Produce a PolicyScope for excluded system modules.
Fortunately, the JDK is still modular even if the tests are run sans modules, so we can use the module API to identify the packages in every system module.
1 parent 32c353c commit 51f3d85

File tree

3 files changed

+53
-20
lines changed

3 files changed

+53
-20
lines changed

libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public class PolicyManager {
5454
*/
5555
static final Logger generalLogger = LogManager.getLogger(PolicyManager.class);
5656

57-
static final Set<String> MODULES_EXCLUDED_FROM_SYSTEM_MODULES = Set.of("java.desktop", "java.xml");
57+
public static final Set<String> MODULES_EXCLUDED_FROM_SYSTEM_MODULES = Set.of("java.desktop", "java.xml");
5858

5959
/**
6060
* Identifies a particular entitlement {@link Scope} within a {@link Policy}.

test/framework/src/main/java/org/elasticsearch/bootstrap/TestScopeResolver.java

Lines changed: 49 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99

1010
package org.elasticsearch.bootstrap;
1111

12+
import org.elasticsearch.core.Nullable;
1213
import org.elasticsearch.core.SuppressForbidden;
13-
import org.elasticsearch.entitlement.runtime.policy.PolicyManager;
14+
import org.elasticsearch.entitlement.runtime.policy.PolicyManager.PolicyScope;
1415
import org.elasticsearch.logging.LogManager;
1516
import org.elasticsearch.logging.Logger;
1617

18+
import java.lang.module.ModuleDescriptor;
19+
import java.lang.module.ModuleFinder;
1720
import java.net.MalformedURLException;
1821
import java.net.URL;
1922
import java.util.List;
@@ -22,49 +25,78 @@
2225
import java.util.TreeMap;
2326
import java.util.function.Function;
2427

28+
import static java.util.Objects.requireNonNull;
29+
import static java.util.stream.Collectors.toSet;
2530
import static org.elasticsearch.entitlement.runtime.policy.PolicyManager.ALL_UNNAMED;
2631
import static org.elasticsearch.entitlement.runtime.policy.PolicyManager.ComponentKind.PLUGIN;
2732
import static org.elasticsearch.entitlement.runtime.policy.PolicyManager.ComponentKind.SERVER;
33+
import static org.elasticsearch.entitlement.runtime.policy.PolicyManager.MODULES_EXCLUDED_FROM_SYSTEM_MODULES;
2834

29-
public record TestScopeResolver(Map<String, PolicyManager.PolicyScope> scopeMap) {
35+
public final class TestScopeResolver {
3036

3137
private static final Logger logger = LogManager.getLogger(TestScopeResolver.class);
38+
private final Map<String, PolicyScope> scopeMap;
39+
private static final Map<String, PolicyScope> excludedSystemPackageScopes = computeExcludedSystemPackageScopes();
3240

33-
PolicyManager.PolicyScope getScope(Class<?> callerClass) {
41+
public TestScopeResolver(Map<String, PolicyScope> scopeMap) {
42+
this.scopeMap = scopeMap;
43+
}
44+
45+
private static Map<String, PolicyScope> computeExcludedSystemPackageScopes() {
46+
// Within any one module layer, module names are unique, so we just need the names
47+
Set<String> systemModuleNames = ModuleFinder.ofSystem()
48+
.findAll()
49+
.stream()
50+
.map(ref -> ref.descriptor().name())
51+
.filter(MODULES_EXCLUDED_FROM_SYSTEM_MODULES::contains)
52+
.collect(toSet());
53+
54+
Map<String, PolicyScope> result = new TreeMap<>();
55+
ModuleLayer.boot().modules().stream().filter(m -> systemModuleNames.contains(m.getName())).forEach(m -> {
56+
ModuleDescriptor desc = m.getDescriptor();
57+
if (desc != null) {
58+
desc.packages().forEach(pkg ->
59+
// Our component identification logic returns SERVER for these
60+
result.put(pkg, new PolicyScope(SERVER, SERVER.componentName, m.getName())));
61+
}
62+
});
63+
return result;
64+
}
65+
66+
public static @Nullable PolicyScope getExcludedSystemPackageScope(Class<?> callerClass) {
67+
return excludedSystemPackageScopes.get(callerClass.getPackageName());
68+
}
69+
70+
PolicyScope getScope(Class<?> callerClass) {
3471
var callerCodeSource = callerClass.getProtectionDomain().getCodeSource();
3572
if (callerCodeSource == null) {
36-
// This case happens for JDK modules. Usually those are trivially allowed, but some are excluded,
37-
// and those end up here.
38-
// We have no test build info for those modules, so for now, let's just guess.
39-
if (callerClass.getPackageName().equals("sun.java2d")) {
40-
return new PolicyManager.PolicyScope(SERVER, SERVER.componentName, "java.desktop");
41-
} else {
42-
throw new IllegalArgumentException("Cannot identify scope for JDK class [" + callerClass + "]");
43-
}
73+
// This only happens for JDK classes. Furthermore, for trivially allowed modules, we shouldn't even get here.
74+
// Hence, this must be an excluded system module, so check for that.
75+
return requireNonNull(getExcludedSystemPackageScope(callerClass));
4476
}
4577

4678
var location = callerCodeSource.getLocation().toString();
4779
var scope = scopeMap.get(location);
4880
if (scope == null) {
4981
// Special cases for libraries not handled by our automatically-generated scopeMap
5082
if (callerClass.getPackageName().startsWith("org.bouncycastle")) {
51-
scope = new PolicyManager.PolicyScope(PLUGIN, "security", ALL_UNNAMED);
83+
scope = new PolicyScope(PLUGIN, "security", ALL_UNNAMED);
5284
logger.debug("Assuming bouncycastle is part of the security plugin");
5385
}
5486
}
5587
if (scope == null) {
5688
logger.warn("Cannot identify a scope for class [{}], location [{}]", callerClass.getName(), location);
57-
return PolicyManager.PolicyScope.unknown(location);
89+
return PolicyScope.unknown(location);
5890
}
5991
return scope;
6092
}
6193

62-
public static Function<Class<?>, PolicyManager.PolicyScope> createScopeResolver(
94+
public static Function<Class<?>, PolicyScope> createScopeResolver(
6395
TestBuildInfo serverBuildInfo,
6496
List<TestBuildInfo> pluginsBuildInfo,
6597
Set<String> modularPlugins
6698
) {
67-
Map<String, PolicyManager.PolicyScope> scopeMap = new TreeMap<>(); // Sorted to make it easier to read during debugging
99+
Map<String, PolicyScope> scopeMap = new TreeMap<>(); // Sorted to make it easier to read during debugging
68100
for (var pluginBuildInfo : pluginsBuildInfo) {
69101
boolean isModular = modularPlugins.contains(pluginBuildInfo.component());
70102
for (var location : pluginBuildInfo.locations()) {
@@ -76,7 +108,7 @@ public static Function<Class<?>, PolicyManager.PolicyScope> createScopeResolver(
76108
String module = isModular ? location.module() : ALL_UNNAMED;
77109
scopeMap.put(
78110
getCodeSource(codeSource, location.representativeClass()),
79-
PolicyManager.PolicyScope.plugin(pluginBuildInfo.component(), module)
111+
PolicyScope.plugin(pluginBuildInfo.component(), module)
80112
);
81113
} catch (MalformedURLException e) {
82114
throw new IllegalArgumentException("Cannot locate class [" + location.representativeClass() + "]", e);
@@ -91,7 +123,7 @@ public static Function<Class<?>, PolicyManager.PolicyScope> createScopeResolver(
91123
continue;
92124
}
93125
try {
94-
scopeMap.put(getCodeSource(classUrl, location.representativeClass()), PolicyManager.PolicyScope.server(location.module()));
126+
scopeMap.put(getCodeSource(classUrl, location.representativeClass()), PolicyScope.server(location.module()));
95127
} catch (MalformedURLException e) {
96128
throw new IllegalArgumentException("Cannot locate class [" + location.representativeClass() + "]", e);
97129
}

test/framework/src/main/java/org/elasticsearch/entitlement/runtime/policy/TestPolicyManager.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
package org.elasticsearch.entitlement.runtime.policy;
1111

12+
import org.elasticsearch.bootstrap.TestScopeResolver;
1213
import org.elasticsearch.common.util.ArrayUtils;
1314
import org.elasticsearch.entitlement.runtime.policy.entitlements.Entitlement;
1415
import org.elasticsearch.test.ESTestCase;
@@ -97,8 +98,8 @@ public final void clearModuleEntitlementsCache() {
9798

9899
@Override
99100
protected boolean isTrustedSystemClass(Class<?> requestingClass) {
100-
if (requestingClass.getPackageName().startsWith("sun.java2d")) {
101-
// This is part of the java.desktop module
101+
if (TestScopeResolver.getExcludedSystemPackageScope(requestingClass) != null) {
102+
// We don't trust the excluded packages even though they are in system modules
102103
return false;
103104
}
104105
ClassLoader loader = requestingClass.getClassLoader();

0 commit comments

Comments
 (0)