Skip to content

Commit 6484f94

Browse files
prdoyleelasticsearchmachine
andauthored
Entitlements for JDK-wide global state changes (elastic#119592)
* Refactor: separate check method name vs signature parsing * Cosmetic: change checker comment format * Entitlements for JDK-wide global state * [CI] Auto commit changes from spotless * Comment explaining entitlement add-exports * @SuppressForbidden * Refactor: rename dummy subclases --------- Co-authored-by: elasticsearchmachine <[email protected]>
1 parent d33e3de commit 6484f94

File tree

11 files changed

+858
-123
lines changed

11 files changed

+858
-123
lines changed

distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/SystemJvmOptions.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,16 @@ private static Stream<String> maybeAttachEntitlementAgent(boolean useEntitlement
167167
} catch (IOException e) {
168168
throw new IllegalStateException("Failed to list entitlement jars in: " + dir, e);
169169
}
170+
// We instrument classes in these modules to call the bridge. Because the bridge gets patched
171+
// into java.base, we must export the bridge from java.base to these modules.
172+
String modulesContainingEntitlementInstrumentation = "java.logging";
170173
return Stream.of(
171174
"-Des.entitlements.enabled=true",
172175
"-XX:+EnableDynamicAgentLoading",
173176
"-Djdk.attach.allowAttachSelf=true",
174177
"--patch-module=java.base=" + bridgeJar,
175-
"--add-exports=java.base/org.elasticsearch.entitlement.bridge=org.elasticsearch.entitlement"
178+
"--add-exports=java.base/org.elasticsearch.entitlement.bridge=org.elasticsearch.entitlement,"
179+
+ modulesContainingEntitlementInstrumentation
176180
);
177181
}
178182
}

libs/entitlement/asm-provider/src/main/java/org/elasticsearch/entitlement/instrumentation/impl/InstrumentationServiceImpl.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public MethodVisitor visitMethod(
6666

6767
private static final Type CLASS_TYPE = Type.getType(Class.class);
6868

69-
static MethodKey parseCheckerMethodSignature(String checkerMethodName, Type[] checkerMethodArgumentTypes) {
69+
static ParsedCheckerMethod parseCheckerMethodName(String checkerMethodName) {
7070
boolean targetMethodIsStatic;
7171
int classNameEndIndex = checkerMethodName.lastIndexOf("$$");
7272
int methodNameStartIndex;
@@ -100,9 +100,14 @@ static MethodKey parseCheckerMethodSignature(String checkerMethodName, Type[] ch
100100
if (targetClassName.isBlank()) {
101101
throw new IllegalArgumentException(String.format(Locale.ROOT, "Checker method %s has no class name", checkerMethodName));
102102
}
103+
return new ParsedCheckerMethod(targetClassName, targetMethodName, targetMethodIsStatic, targetMethodIsCtor);
104+
}
105+
106+
static MethodKey parseCheckerMethodSignature(String checkerMethodName, Type[] checkerMethodArgumentTypes) {
107+
ParsedCheckerMethod checkerMethod = parseCheckerMethodName(checkerMethodName);
103108

104109
final List<String> targetParameterTypes;
105-
if (targetMethodIsStatic || targetMethodIsCtor) {
110+
if (checkerMethod.targetMethodIsStatic() || checkerMethod.targetMethodIsCtor()) {
106111
if (checkerMethodArgumentTypes.length < 1 || CLASS_TYPE.equals(checkerMethodArgumentTypes[0]) == false) {
107112
throw new IllegalArgumentException(
108113
String.format(
@@ -130,7 +135,13 @@ static MethodKey parseCheckerMethodSignature(String checkerMethodName, Type[] ch
130135
}
131136
targetParameterTypes = Arrays.stream(checkerMethodArgumentTypes).skip(2).map(Type::getInternalName).toList();
132137
}
133-
boolean hasReceiver = (targetMethodIsStatic || targetMethodIsCtor) == false;
134-
return new MethodKey(targetClassName, targetMethodName, targetParameterTypes);
138+
return new MethodKey(checkerMethod.targetClassName(), checkerMethod.targetMethodName(), targetParameterTypes);
135139
}
140+
141+
private record ParsedCheckerMethod(
142+
String targetClassName,
143+
String targetMethodName,
144+
boolean targetMethodIsStatic,
145+
boolean targetMethodIsCtor
146+
) {}
136147
}

libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99

1010
package org.elasticsearch.entitlement.bridge;
1111

12+
import java.io.InputStream;
13+
import java.io.PrintStream;
14+
import java.io.PrintWriter;
15+
import java.net.ContentHandlerFactory;
16+
import java.net.DatagramSocketImplFactory;
17+
import java.net.FileNameMap;
18+
import java.net.SocketImplFactory;
1219
import java.net.URL;
1320
import java.net.URLStreamHandlerFactory;
1421
import java.util.List;
@@ -21,26 +28,42 @@
2128
@SuppressWarnings("unused") // Called from instrumentation code inserted by the Entitlements agent
2229
public interface EntitlementChecker {
2330

31+
////////////////////
32+
//
2433
// Exit the JVM process
34+
//
35+
2536
void check$java_lang_Runtime$exit(Class<?> callerClass, Runtime runtime, int status);
2637

2738
void check$java_lang_Runtime$halt(Class<?> callerClass, Runtime runtime, int status);
2839

40+
////////////////////
41+
//
2942
// ClassLoader ctor
43+
//
44+
3045
void check$java_lang_ClassLoader$(Class<?> callerClass);
3146

3247
void check$java_lang_ClassLoader$(Class<?> callerClass, ClassLoader parent);
3348

3449
void check$java_lang_ClassLoader$(Class<?> callerClass, String name, ClassLoader parent);
3550

51+
////////////////////
52+
//
3653
// SecureClassLoader ctor
54+
//
55+
3756
void check$java_security_SecureClassLoader$(Class<?> callerClass);
3857

3958
void check$java_security_SecureClassLoader$(Class<?> callerClass, ClassLoader parent);
4059

4160
void check$java_security_SecureClassLoader$(Class<?> callerClass, String name, ClassLoader parent);
4261

62+
////////////////////
63+
//
4364
// URLClassLoader constructors
65+
//
66+
4467
void check$java_net_URLClassLoader$(Class<?> callerClass, URL[] urls);
4568

4669
void check$java_net_URLClassLoader$(Class<?> callerClass, URL[] urls, ClassLoader parent);
@@ -51,7 +74,11 @@ public interface EntitlementChecker {
5174

5275
void check$java_net_URLClassLoader$(Class<?> callerClass, String name, URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory);
5376

77+
////////////////////
78+
//
5479
// "setFactory" methods
80+
//
81+
5582
void check$javax_net_ssl_HttpsURLConnection$setSSLSocketFactory(Class<?> callerClass, HttpsURLConnection conn, SSLSocketFactory sf);
5683

5784
void check$javax_net_ssl_HttpsURLConnection$$setDefaultSSLSocketFactory(Class<?> callerClass, SSLSocketFactory sf);
@@ -60,9 +87,82 @@ public interface EntitlementChecker {
6087

6188
void check$javax_net_ssl_SSLContext$$setDefault(Class<?> callerClass, SSLContext context);
6289

90+
////////////////////
91+
//
6392
// Process creation
93+
//
94+
6495
void check$java_lang_ProcessBuilder$start(Class<?> callerClass, ProcessBuilder that);
6596

6697
void check$java_lang_ProcessBuilder$$startPipeline(Class<?> callerClass, List<ProcessBuilder> builders);
6798

99+
////////////////////
100+
//
101+
// JVM-wide state changes
102+
//
103+
104+
void check$java_lang_System$$setIn(Class<?> callerClass, InputStream in);
105+
106+
void check$java_lang_System$$setOut(Class<?> callerClass, PrintStream out);
107+
108+
void check$java_lang_System$$setErr(Class<?> callerClass, PrintStream err);
109+
110+
void check$java_lang_Runtime$addShutdownHook(Class<?> callerClass, Runtime runtime, Thread hook);
111+
112+
void check$java_lang_Runtime$removeShutdownHook(Class<?> callerClass, Runtime runtime, Thread hook);
113+
114+
void check$jdk_tools_jlink_internal_Jlink$(Class<?> callerClass);
115+
116+
void check$jdk_tools_jlink_internal_Main$$run(Class<?> callerClass, PrintWriter out, PrintWriter err, String... args);
117+
118+
void check$jdk_vm_ci_services_JVMCIServiceLocator$$getProviders(Class<?> callerClass, Class<?> service);
119+
120+
void check$jdk_vm_ci_services_Services$$load(Class<?> callerClass, Class<?> service);
121+
122+
void check$jdk_vm_ci_services_Services$$loadSingle(Class<?> callerClass, Class<?> service, boolean required);
123+
124+
void check$com_sun_tools_jdi_VirtualMachineManagerImpl$$virtualMachineManager(Class<?> callerClass);
125+
126+
void check$java_lang_Thread$$setDefaultUncaughtExceptionHandler(Class<?> callerClass, Thread.UncaughtExceptionHandler ueh);
127+
128+
void check$java_util_spi_LocaleServiceProvider$(Class<?> callerClass);
129+
130+
void check$java_text_spi_BreakIteratorProvider$(Class<?> callerClass);
131+
132+
void check$java_text_spi_CollatorProvider$(Class<?> callerClass);
133+
134+
void check$java_text_spi_DateFormatProvider$(Class<?> callerClass);
135+
136+
void check$java_text_spi_DateFormatSymbolsProvider$(Class<?> callerClass);
137+
138+
void check$java_text_spi_DecimalFormatSymbolsProvider$(Class<?> callerClass);
139+
140+
void check$java_text_spi_NumberFormatProvider$(Class<?> callerClass);
141+
142+
void check$java_util_spi_CalendarDataProvider$(Class<?> callerClass);
143+
144+
void check$java_util_spi_CalendarNameProvider$(Class<?> callerClass);
145+
146+
void check$java_util_spi_CurrencyNameProvider$(Class<?> callerClass);
147+
148+
void check$java_util_spi_LocaleNameProvider$(Class<?> callerClass);
149+
150+
void check$java_util_spi_TimeZoneNameProvider$(Class<?> callerClass);
151+
152+
void check$java_util_logging_LogManager$(Class<?> callerClass);
153+
154+
void check$java_net_DatagramSocket$$setDatagramSocketImplFactory(Class<?> callerClass, DatagramSocketImplFactory fac);
155+
156+
void check$java_net_HttpURLConnection$$setFollowRedirects(Class<?> callerClass, boolean set);
157+
158+
void check$java_net_ServerSocket$$setSocketFactory(Class<?> callerClass, SocketImplFactory fac);
159+
160+
void check$java_net_Socket$$setSocketImplFactory(Class<?> callerClass, SocketImplFactory fac);
161+
162+
void check$java_net_URL$$setURLStreamHandlerFactory(Class<?> callerClass, URLStreamHandlerFactory fac);
163+
164+
void check$java_net_URLConnection$$setFileNameMap(Class<?> callerClass, FileNameMap map);
165+
166+
void check$java_net_URLConnection$$setContentHandlerFactory(Class<?> callerClass, ContentHandlerFactory fac);
167+
68168
}

libs/entitlement/qa/common/src/main/java/module-info.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,8 @@
1212
requires org.elasticsearch.base;
1313
requires org.elasticsearch.logging;
1414

15+
// Modules we'll attempt to use in order to exercise entitlements
16+
requires java.logging;
17+
1518
exports org.elasticsearch.entitlement.qa.common;
1619
}

0 commit comments

Comments
 (0)