From 3464adb3aed66bc8a1c91c1a754479d6f9da18d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lorenzo=20Dematt=C3=A9?= Date: Wed, 8 Jan 2025 10:24:03 +0100 Subject: [PATCH] Adjust Bootstrap and JVM options to ensure the SM is never used when entitlements are enabled (#119689) --- .../elasticsearch/server/cli/SystemJvmOptions.java | 6 +++--- .../org/elasticsearch/bootstrap/Bootstrap.java | 8 +++++++- .../elasticsearch/bootstrap/BootstrapChecks.java | 1 - .../org/elasticsearch/bootstrap/Elasticsearch.java | 14 ++++++++++---- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/SystemJvmOptions.java b/distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/SystemJvmOptions.java index ce951715939f0..928a8ba43cae1 100644 --- a/distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/SystemJvmOptions.java +++ b/distribution/tools/server-cli/src/main/java/org/elasticsearch/server/cli/SystemJvmOptions.java @@ -71,7 +71,7 @@ static List systemJvmOptions(Settings nodeSettings, final Map s).toList(); } @@ -140,8 +140,8 @@ private static Stream maybeWorkaroundG1Bug() { } @UpdateForV9(owner = UpdateForV9.Owner.CORE_INFRA) - private static Stream maybeAllowSecurityManager() { - if (RuntimeVersionFeature.isSecurityManagerAvailable()) { + private static Stream maybeAllowSecurityManager(boolean useEntitlements) { + if (useEntitlements == false && RuntimeVersionFeature.isSecurityManagerAvailable()) { // Will become conditional on useEntitlements once entitlements can run without SM return Stream.of("-Djava.security.manager=allow"); } diff --git a/server/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java b/server/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java index 56d185645e149..4c7fb96c5b1d5 100644 --- a/server/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java +++ b/server/src/main/java/org/elasticsearch/bootstrap/Bootstrap.java @@ -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(); @@ -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 = 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() { @@ -60,6 +62,10 @@ Spawner spawner() { return spawner; } + public boolean useEntitlements() { + return useEntitlements; + } + void setSecureSettings(SecureSettings secureSettings) { this.secureSettings.set(secureSettings); } diff --git a/server/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java b/server/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java index 7b2f0c2c894be..b5b616fff0182 100644 --- a/server/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java +++ b/server/src/main/java/org/elasticsearch/bootstrap/BootstrapChecks.java @@ -212,7 +212,6 @@ static List 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); diff --git a/server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java b/server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java index 6822c201ab030..f26bf96cc2211 100644 --- a/server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java +++ b/server/src/main/java/org/elasticsearch/bootstrap/Elasticsearch.java @@ -54,6 +54,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; @@ -108,6 +109,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(); @@ -116,7 +118,7 @@ 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. */ - if (RuntimeVersionFeature.isSecurityManagerAvailable()) { + if (useEntitlements == false && RuntimeVersionFeature.isSecurityManagerAvailable()) { org.elasticsearch.bootstrap.Security.setSecurityManager(new SecurityManager() { @Override public void checkPermission(Permission perm) { @@ -149,7 +151,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); } /** @@ -214,7 +216,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 pluginData = Stream.concat( @@ -280,7 +282,11 @@ protected void validateNodeBeforeAcceptingRequests( final BoundTransportAddress boundTransportAddress, List 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);