Skip to content

Commit

Permalink
Adjust Bootstrap and JVM options to ensure the SM is never used when …
Browse files Browse the repository at this point in the history
…entitlements are enabled (#119689) (#119741)
  • Loading branch information
ldematte authored Jan 8, 2025
1 parent 979f58d commit a62f9e4
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ static List<String> systemJvmOptions(Settings nodeSettings, final Map<String, St
maybeSetActiveProcessorCount(nodeSettings),
maybeSetReplayFile(distroType, isHotspot),
maybeWorkaroundG1Bug(),
maybeAllowSecurityManager(),
maybeAllowSecurityManager(useEntitlements),
maybeAttachEntitlementAgent(useEntitlements)
).flatMap(s -> s).toList();
}
Expand Down Expand Up @@ -148,9 +148,12 @@ private static Stream<String> maybeWorkaroundG1Bug() {
return Stream.of();
}

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

private static Stream<String> maybeAttachEntitlementAgent(boolean useEntitlements) {
Expand All @@ -172,12 +175,16 @@ private static Stream<String> maybeAttachEntitlementAgent(boolean useEntitlement
} catch (IOException e) {
throw new IllegalStateException("Failed to list entitlement jars in: " + dir, e);
}
// We instrument classes in these modules to call the bridge. Because the bridge gets patched
// into java.base, we must export the bridge from java.base to these modules.
String modulesContainingEntitlementInstrumentation = "java.logging";
return Stream.of(
"-Des.entitlements.enabled=true",
"-XX:+EnableDynamicAgentLoading",
"-Djdk.attach.allowAttachSelf=true",
"--patch-module=java.base=" + bridgeJar,
"--add-exports=java.base/org.elasticsearch.entitlement.bridge=org.elasticsearch.entitlement"
"--add-exports=java.base/org.elasticsearch.entitlement.bridge=org.elasticsearch.entitlement,"
+ modulesContainingEntitlementInstrumentation
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class Bootstrap {

// arguments from the CLI process
private final ServerArgs args;
private final boolean useEntitlements;

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

Bootstrap(PrintStream out, PrintStream err, ServerArgs args) {
Bootstrap(PrintStream out, PrintStream err, ServerArgs args, boolean useEntitlements) {
this.out = out;
this.err = err;
this.args = args;
this.useEntitlements = useEntitlements;
}

ServerArgs args() {
Expand All @@ -60,6 +62,10 @@ Spawner spawner() {
return spawner;
}

public boolean useEntitlements() {
return useEntitlements;
}

void setSecureSettings(SecureSettings secureSettings) {
this.secureSettings.set(secureSettings);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,6 @@ static List<BootstrapCheck> checks() {
checks.add(new OnErrorCheck());
checks.add(new OnOutOfMemoryErrorCheck());
checks.add(new EarlyAccessCheck());
checks.add(new AllPermissionCheck());
checks.add(new DiscoveryConfiguredCheck());
checks.add(new ByteOrderCheck());
return Collections.unmodifiableList(checks);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import java.nio.file.Path;
import java.security.Permission;
import java.security.Security;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
Expand Down Expand Up @@ -105,6 +106,7 @@ private static Bootstrap initPhase1() {
final PrintStream out = getStdout();
final PrintStream err = getStderr();
final ServerArgs args;
final boolean useEntitlements = Boolean.parseBoolean(System.getProperty("es.entitlements.enabled"));
try {
initSecurityProperties();

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

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

return new Bootstrap(out, err, args);
return new Bootstrap(out, err, args, useEntitlements);
}

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

if (Boolean.parseBoolean(System.getProperty("es.entitlements.enabled"))) {
if (bootstrap.useEntitlements()) {
LogManager.getLogger(Elasticsearch.class).info("Bootstrapping Entitlements");

List<EntitlementBootstrap.PluginData> pluginData = Stream.concat(
Expand Down Expand Up @@ -269,7 +273,11 @@ protected void validateNodeBeforeAcceptingRequests(
final BoundTransportAddress boundTransportAddress,
List<BootstrapCheck> checks
) throws NodeValidationException {
BootstrapChecks.check(context, boundTransportAddress, checks);
var additionalChecks = new ArrayList<>(checks);
if (bootstrap.useEntitlements() == false) {
additionalChecks.add(new BootstrapChecks.AllPermissionCheck());
}
BootstrapChecks.check(context, boundTransportAddress, additionalChecks);
}
};
INSTANCE = new Elasticsearch(bootstrap.spawner(), node);
Expand Down

0 comments on commit a62f9e4

Please sign in to comment.