-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[POC] [Security Manager Replacement] GraalVM sandboxing
Signed-off-by: Andriy Redko <[email protected]>
- Loading branch information
Showing
4 changed files
with
229 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
* | ||
* Modifications Copyright OpenSearch Contributors. See | ||
* GitHub history for details. | ||
*/ | ||
|
||
import org.opensearch.gradle.info.BuildParams | ||
|
||
apply plugin: 'opensearch.publish' | ||
|
||
base { | ||
archivesName = 'esspresso-sm' | ||
} | ||
|
||
dependencies { | ||
implementation "org.graalvm.polyglot:polyglot:24.1.1" | ||
implementation "org.graalvm.sdk:nativeimage:24.1.1" | ||
implementation "org.graalvm.sdk:collections:24.1.1" | ||
implementation "org.graalvm.sdk:word:24.1.1" | ||
implementation "org.graalvm.sdk:jniutils:24.1.1" | ||
implementation "org.graalvm.llvm:llvm-api:24.1.1" | ||
implementation "org.graalvm.llvm:llvm-language:24.1.1" | ||
implementation "org.graalvm.llvm:llvm-language-native:24.1.1" | ||
implementation "org.graalvm.llvm:llvm-language-native-resources:24.1.1" | ||
implementation "org.graalvm.llvm:llvm-language-nfi:24.1.1" | ||
implementation "org.graalvm.truffle:truffle-api:24.1.1" | ||
implementation "org.graalvm.truffle:truffle-compiler:24.1.1" | ||
implementation "org.graalvm.truffle:truffle-nfi:24.1.1" | ||
implementation "org.graalvm.truffle:truffle-nfi-libffi:24.1.1" | ||
implementation "org.graalvm.truffle:truffle-runtime:24.1.1" | ||
implementation "org.graalvm.espresso:espresso-language:24.1.1" | ||
implementation "org.graalvm.espresso:espresso-libs-resources-linux-amd64:24.1.1" | ||
implementation "org.graalvm.espresso:espresso-runtime-resources-linux-amd64:24.1.1" | ||
implementation project(":server") | ||
} | ||
|
||
tasks.named('forbiddenApisMain').configure { | ||
replaceSignatureFiles 'jdk-signatures' | ||
} |
113 changes: 113 additions & 0 deletions
113
libs/espresso-sm/src/main/java/org/opensearch/espresso/sandbox/Sandbox.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
/* | ||
* Modifications Copyright OpenSearch Contributors. See | ||
* GitHub history for details. | ||
*/ | ||
|
||
package org.opensearch.espresso.sandbox; | ||
|
||
import org.opensearch.client.Client; | ||
import org.opensearch.client.node.NodeClient; | ||
import org.opensearch.common.settings.Settings; | ||
import org.opensearch.threadpool.ThreadPool; | ||
|
||
import java.io.File; | ||
import java.io.IOException; | ||
import java.nio.file.Path; | ||
|
||
import org.graalvm.polyglot.Context; | ||
import org.graalvm.polyglot.Engine; | ||
import org.graalvm.polyglot.HostAccess; | ||
import org.graalvm.polyglot.PolyglotAccess; | ||
import org.graalvm.polyglot.Value; | ||
import org.graalvm.polyglot.io.IOAccess; | ||
|
||
/** | ||
* GraalVM Sandbox | ||
*/ | ||
public class Sandbox { | ||
/** | ||
* GraalVM Sandbox runner | ||
*/ | ||
public static void main(String[] args) throws IOException, InterruptedException { | ||
final String opensearchHome = args[0]; | ||
System.out.println("OpenSearch home: " + opensearchHome); | ||
|
||
final Engine engine = Engine.newBuilder().build(); | ||
|
||
System.out.println("Host JVM version: " + Runtime.version()); | ||
final String plugin = loadPlugin(opensearchHome, engine); | ||
System.out.println(plugin); | ||
} | ||
|
||
private static String loadPlugin(String opensearchHome, Engine engine) throws IOException { | ||
// See please: | ||
// - https://github.com/oracle/graal/issues/10239 | ||
// - | ||
// https://github.com/oracle/graal/blob/master/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/EspressoOptions.java | ||
// - | ||
// https://github.com/oracle/graal/blob/master/espresso/src/com.oracle.truffle.espresso.launcher/src/com/oracle/truffle/espresso/launcher/EspressoLauncher.java | ||
final Context context = Context.newBuilder("java") | ||
.option("java.JavaHome", "/usr/lib/jvm/java-21-openjdk-amd64/") | ||
.option( | ||
"java.Classpath", | ||
("${opensearchHome}/lib/lucene-core-9.12.0.jar:" | ||
+ "${opensearchHome}/lib/opensearch-cli-3.0.0-SNAPSHOT.jar:" | ||
+ "${opensearchHome}/lib/jackson-core-2.17.2.jar:" | ||
+ "${opensearchHome}/lib/jackson-dataformat-cbor-2.17.2.jar:" | ||
+ "${opensearchHome}/lib/jackson-dataformat-smile-2.17.2.jar:" | ||
+ "${opensearchHome}/lib/jackson-dataformat-yaml-2.17.2.jar:" | ||
+ "${opensearchHome}/lib/snakeyaml-2.1.jar:" | ||
+ "${opensearchHome}/lib/opensearch-3.0.0-SNAPSHOT.jar:" | ||
+ "${opensearchHome}/lib/opensearch-core-3.0.0-SNAPSHOT.jar:" | ||
+ "${opensearchHome}/lib/opensearch-common-3.0.0-SNAPSHOT.jar:" | ||
+ "${opensearchHome}/lib/opensearch-x-content-3.0.0-SNAPSHOT.jar:" | ||
+ "${opensearchHome}/lib/opensearch-secure-sm-3.0.0-SNAPSHOT.jar:" | ||
+ "${opensearchHome}/lib/log4j-core-2.21.0.jar:" | ||
+ "${opensearchHome}/lib/log4j-jul-2.21.0.jar:" | ||
+ "${opensearchHome}/lib/log4j-api-2.21.0.jar:" | ||
+ "${opensearchHome}/plugins/identity-shiro/slf4j-api-1.7.36.jar:" | ||
+ "${opensearchHome}/plugins/identity-shiro/passay-1.6.3.jar:" | ||
+ "${opensearchHome}/plugins/identity-shiro/identity-shiro-3.0.0-SNAPSHOT.jar:" | ||
+ "${opensearchHome}/plugins/identity-shiro/shiro-core-1.13.0.jar").replaceAll( | ||
"[$][{]opensearchHome[}]", | ||
opensearchHome | ||
) | ||
) | ||
.option("java.Properties.java.security.manager", "allow") | ||
.option("java.PolyglotInterfaceMappings", getInterfaceMappings()) | ||
.option("java.Polyglot", "true") | ||
.allowExperimentalOptions(true) | ||
.allowNativeAccess(true) | ||
.allowCreateThread(true) | ||
.allowHostAccess(HostAccess.NONE) | ||
.allowIO(IOAccess.NONE) | ||
.allowPolyglotAccess(PolyglotAccess.newBuilder().allowBindingsAccess("java").build()) | ||
.engine(engine) | ||
.build(); | ||
|
||
final Value runtime = context.getBindings("java").getMember("java.lang.Runtime"); | ||
System.out.println("Polyglot JVM version: " + runtime.invokeMember("version").toString()); | ||
|
||
final Path homePath = new File(opensearchHome).toPath(); | ||
final Path configPath = new File(opensearchHome + "/config").toPath(); | ||
context.getBindings("java") | ||
.getMember("org.opensearch.bootstrap.QuickBoostrap") | ||
.invokeMember("bootstrap", configPath.toString(), homePath.toString()); | ||
|
||
final Value securityManager = context.getBindings("java").getMember("java.lang.System").invokeMember("getSecurityManager"); | ||
System.out.println("Security Manager? " + securityManager.toString()); | ||
|
||
final Value settings = context.getBindings("java").getMember("org.opensearch.common.settings.Settings").getMember("EMPTY"); | ||
final Value result = context.getBindings("java").getMember("org.opensearch.identity.shiro.ShiroIdentityPlugin"); | ||
final Value instance = result.newInstance(settings); | ||
System.out.println("Shiro Plugin? " + instance.toString()); | ||
|
||
final Client client = new NodeClient(Settings.EMPTY, new ThreadPool(Settings.EMPTY)); | ||
final Value socket = instance.invokeMember("getSocket", client); | ||
return socket.toString(); | ||
} | ||
|
||
private static String getInterfaceMappings() { | ||
return "org.opensearch.client.Client;" + "org.opensearch.client.AdminClient;"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
60 changes: 60 additions & 0 deletions
60
server/src/main/java/org/opensearch/bootstrap/QuickBoostrap.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
/* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
* | ||
* The OpenSearch Contributors require contributions made to | ||
* this file be licensed under the Apache-2.0 license or a | ||
* compatible open source license. | ||
*/ | ||
|
||
package org.opensearch.bootstrap; | ||
|
||
import org.opensearch.cli.UserException; | ||
import org.opensearch.common.logging.LogConfigurator; | ||
import org.opensearch.common.settings.Settings; | ||
import org.opensearch.env.Environment; | ||
import org.opensearch.node.InternalSettingsPreparer; | ||
import org.opensearch.node.Node; | ||
import org.opensearch.node.NodeValidationException; | ||
|
||
import java.io.IOException; | ||
import java.nio.file.Paths; | ||
import java.security.NoSuchAlgorithmException; | ||
import java.util.Collections; | ||
|
||
/** | ||
* Quick bootstrap | ||
*/ | ||
public class QuickBoostrap { | ||
/** | ||
* This method is invoked by {@link OpenSearch#main(String[])} to startup opensearch. | ||
*/ | ||
public static void bootstrap(final String configPath, final String homePath) throws BootstrapException, NodeValidationException, | ||
UserException { | ||
|
||
// force the class initializer for BootstrapInfo to run before | ||
// the security manager is installed | ||
BootstrapInfo.init(); | ||
|
||
Settings settings = Settings.builder().put(Environment.PATH_HOME_SETTING.getKey(), homePath).build(); | ||
final Environment environment = InternalSettingsPreparer.prepareEnvironment( | ||
settings, | ||
Collections.emptyMap(), | ||
Paths.get(configPath), | ||
// HOSTNAME is set by opensearch-env and opensearch-env.bat so it is always available | ||
() -> System.getenv("HOSTNAME") | ||
); | ||
|
||
LogConfigurator.setNodeName(Node.NODE_NAME_SETTING.get(environment.settings())); | ||
try { | ||
LogConfigurator.configure(environment); | ||
} catch (IOException e) { | ||
throw new BootstrapException(e); | ||
} | ||
|
||
try { | ||
Security.configure(environment, BootstrapSettings.SECURITY_FILTER_BAD_DEFAULTS_SETTING.get(settings)); | ||
} catch (IOException | NoSuchAlgorithmException e) { | ||
throw new BootstrapException(e); | ||
} | ||
} | ||
} |