Skip to content

Commit a62f9e4

Browse files
authored
Adjust Bootstrap and JVM options to ensure the SM is never used when entitlements are enabled (#119689) (#119741)
1 parent 979f58d commit a62f9e4

File tree

4 files changed

+36
-16
lines changed

4 files changed

+36
-16
lines changed

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ static List<String> systemJvmOptions(Settings nodeSettings, final Map<String, St
7070
maybeSetActiveProcessorCount(nodeSettings),
7171
maybeSetReplayFile(distroType, isHotspot),
7272
maybeWorkaroundG1Bug(),
73-
maybeAllowSecurityManager(),
73+
maybeAllowSecurityManager(useEntitlements),
7474
maybeAttachEntitlementAgent(useEntitlements)
7575
).flatMap(s -> s).toList();
7676
}
@@ -148,9 +148,12 @@ private static Stream<String> maybeWorkaroundG1Bug() {
148148
return Stream.of();
149149
}
150150

151-
private static Stream<String> maybeAllowSecurityManager() {
152-
// Will become conditional on useEntitlements once entitlements can run without SM
153-
return Stream.of("-Djava.security.manager=allow");
151+
private static Stream<String> maybeAllowSecurityManager(boolean useEntitlements) {
152+
if (useEntitlements == false) {
153+
// Will become conditional on useEntitlements once entitlements can run without SM
154+
return Stream.of("-Djava.security.manager=allow");
155+
}
156+
return Stream.of();
154157
}
155158

156159
private static Stream<String> maybeAttachEntitlementAgent(boolean useEntitlements) {
@@ -172,12 +175,16 @@ private static Stream<String> maybeAttachEntitlementAgent(boolean useEntitlement
172175
} catch (IOException e) {
173176
throw new IllegalStateException("Failed to list entitlement jars in: " + dir, e);
174177
}
178+
// We instrument classes in these modules to call the bridge. Because the bridge gets patched
179+
// into java.base, we must export the bridge from java.base to these modules.
180+
String modulesContainingEntitlementInstrumentation = "java.logging";
175181
return Stream.of(
176182
"-Des.entitlements.enabled=true",
177183
"-XX:+EnableDynamicAgentLoading",
178184
"-Djdk.attach.allowAttachSelf=true",
179185
"--patch-module=java.base=" + bridgeJar,
180-
"--add-exports=java.base/org.elasticsearch.entitlement.bridge=org.elasticsearch.entitlement"
186+
"--add-exports=java.base/org.elasticsearch.entitlement.bridge=org.elasticsearch.entitlement,"
187+
+ modulesContainingEntitlementInstrumentation
181188
);
182189
}
183190
}

server/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class Bootstrap {
3333

3434
// arguments from the CLI process
3535
private final ServerArgs args;
36+
private final boolean useEntitlements;
3637

3738
// controller for spawning component subprocesses
3839
private final Spawner spawner = new Spawner();
@@ -46,10 +47,11 @@ class Bootstrap {
4647
// loads information about plugins required for entitlements in phase 2, used by plugins service in phase 3
4748
private final SetOnce<PluginsLoader> pluginsLoader = new SetOnce<>();
4849

49-
Bootstrap(PrintStream out, PrintStream err, ServerArgs args) {
50+
Bootstrap(PrintStream out, PrintStream err, ServerArgs args, boolean useEntitlements) {
5051
this.out = out;
5152
this.err = err;
5253
this.args = args;
54+
this.useEntitlements = useEntitlements;
5355
}
5456

5557
ServerArgs args() {
@@ -60,6 +62,10 @@ Spawner spawner() {
6062
return spawner;
6163
}
6264

65+
public boolean useEntitlements() {
66+
return useEntitlements;
67+
}
68+
6369
void setSecureSettings(SecureSettings secureSettings) {
6470
this.secureSettings.set(secureSettings);
6571
}

server/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ static List<BootstrapCheck> checks() {
211211
checks.add(new OnErrorCheck());
212212
checks.add(new OnOutOfMemoryErrorCheck());
213213
checks.add(new EarlyAccessCheck());
214-
checks.add(new AllPermissionCheck());
215214
checks.add(new DiscoveryConfiguredCheck());
216215
checks.add(new ByteOrderCheck());
217216
return Collections.unmodifiableList(checks);

server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import java.nio.file.Path;
5252
import java.security.Permission;
5353
import java.security.Security;
54+
import java.util.ArrayList;
5455
import java.util.List;
5556
import java.util.Objects;
5657
import java.util.concurrent.CountDownLatch;
@@ -105,6 +106,7 @@ private static Bootstrap initPhase1() {
105106
final PrintStream out = getStdout();
106107
final PrintStream err = getStderr();
107108
final ServerArgs args;
109+
final boolean useEntitlements = Boolean.parseBoolean(System.getProperty("es.entitlements.enabled"));
108110
try {
109111
initSecurityProperties();
110112

@@ -113,12 +115,14 @@ private static Bootstrap initPhase1() {
113115
* the presence of a security manager or lack thereof act as if there is a security manager present (e.g., DNS cache policy).
114116
* This forces such policies to take effect immediately.
115117
*/
116-
org.elasticsearch.bootstrap.Security.setSecurityManager(new SecurityManager() {
117-
@Override
118-
public void checkPermission(Permission perm) {
119-
// grant all permissions so that we can later set the security manager to the one that we want
120-
}
121-
});
118+
if (useEntitlements == false) {
119+
org.elasticsearch.bootstrap.Security.setSecurityManager(new SecurityManager() {
120+
@Override
121+
public void checkPermission(Permission perm) {
122+
// grant all permissions so that we can later set the security manager to the one that we want
123+
}
124+
});
125+
}
122126
LogConfigurator.registerErrorListener();
123127

124128
BootstrapInfo.init();
@@ -144,7 +148,7 @@ public void checkPermission(Permission perm) {
144148
return null; // unreachable, to satisfy compiler
145149
}
146150

147-
return new Bootstrap(out, err, args);
151+
return new Bootstrap(out, err, args, useEntitlements);
148152
}
149153

150154
/**
@@ -205,7 +209,7 @@ private static void initPhase2(Bootstrap bootstrap) throws IOException {
205209
var pluginsLoader = PluginsLoader.createPluginsLoader(nodeEnv.modulesFile(), nodeEnv.pluginsFile());
206210
bootstrap.setPluginsLoader(pluginsLoader);
207211

208-
if (Boolean.parseBoolean(System.getProperty("es.entitlements.enabled"))) {
212+
if (bootstrap.useEntitlements()) {
209213
LogManager.getLogger(Elasticsearch.class).info("Bootstrapping Entitlements");
210214

211215
List<EntitlementBootstrap.PluginData> pluginData = Stream.concat(
@@ -269,7 +273,11 @@ protected void validateNodeBeforeAcceptingRequests(
269273
final BoundTransportAddress boundTransportAddress,
270274
List<BootstrapCheck> checks
271275
) throws NodeValidationException {
272-
BootstrapChecks.check(context, boundTransportAddress, checks);
276+
var additionalChecks = new ArrayList<>(checks);
277+
if (bootstrap.useEntitlements() == false) {
278+
additionalChecks.add(new BootstrapChecks.AllPermissionCheck());
279+
}
280+
BootstrapChecks.check(context, boundTransportAddress, additionalChecks);
273281
}
274282
};
275283
INSTANCE = new Elasticsearch(bootstrap.spawner(), node);

0 commit comments

Comments
 (0)