Skip to content

Commit 72ab00d

Browse files
authored
[Entitlements] Policy and checks for loading native libraries (#120044) (#120623)
1 parent 4b286ad commit 72ab00d

File tree

12 files changed

+127
-3
lines changed

12 files changed

+127
-3
lines changed

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,4 +398,16 @@ public interface EntitlementChecker {
398398
void check$sun_nio_ch_DatagramChannelImpl$send(Class<?> callerClass, DatagramChannel that, ByteBuffer src, SocketAddress target);
399399

400400
void check$sun_nio_ch_DatagramChannelImpl$receive(Class<?> callerClass, DatagramChannel that, ByteBuffer dst);
401+
402+
////////////////////
403+
//
404+
// Load native libraries
405+
//
406+
void check$java_lang_Runtime$load(Class<?> callerClass, Runtime that, String filename);
407+
408+
void check$java_lang_Runtime$loadLibrary(Class<?> callerClass, Runtime that, String libname);
409+
410+
void check$java_lang_System$$load(Class<?> callerClass, String filename);
411+
412+
void check$java_lang_System$$loadLibrary(Class<?> callerClass, String libname);
401413
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.entitlement.qa.common;
11+
12+
class LoadNativeLibrariesCheckActions {
13+
static void runtimeLoad() {
14+
try {
15+
Runtime.getRuntime().load("libSomeLibFile.so");
16+
} catch (UnsatisfiedLinkError ignored) {
17+
// The library does not exist, so we expect to fail loading it
18+
}
19+
}
20+
21+
static void systemLoad() {
22+
try {
23+
System.load("libSomeLibFile.so");
24+
} catch (UnsatisfiedLinkError ignored) {
25+
// The library does not exist, so we expect to fail loading it
26+
}
27+
}
28+
29+
static void runtimeLoadLibrary() {
30+
try {
31+
Runtime.getRuntime().loadLibrary("SomeLib");
32+
} catch (UnsatisfiedLinkError ignored) {
33+
// The library does not exist, so we expect to fail loading it
34+
}
35+
}
36+
37+
static void systemLoadLibrary() {
38+
try {
39+
System.loadLibrary("SomeLib");
40+
} catch (UnsatisfiedLinkError ignored) {
41+
// The library does not exist, so we expect to fail loading it
42+
}
43+
}
44+
}

libs/entitlement/qa/common/src/main/java/org/elasticsearch/entitlement/qa/common/RestEntitlementsCheckAction.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,12 @@ static CheckAction alwaysDenied(CheckedRunnable<Exception> action) {
192192
entry("datagram_channel_bind", forPlugins(NetworkAccessCheckActions::datagramChannelBind)),
193193
entry("datagram_channel_connect", forPlugins(NetworkAccessCheckActions::datagramChannelConnect)),
194194
entry("datagram_channel_send", forPlugins(NetworkAccessCheckActions::datagramChannelSend)),
195-
entry("datagram_channel_receive", forPlugins(NetworkAccessCheckActions::datagramChannelReceive))
195+
entry("datagram_channel_receive", forPlugins(NetworkAccessCheckActions::datagramChannelReceive)),
196+
197+
entry("runtime_load", forPlugins(LoadNativeLibrariesCheckActions::runtimeLoad)),
198+
entry("runtime_load_library", forPlugins(LoadNativeLibrariesCheckActions::runtimeLoadLibrary)),
199+
entry("system_load", forPlugins(LoadNativeLibrariesCheckActions::systemLoad)),
200+
entry("system_load_library", forPlugins(LoadNativeLibrariesCheckActions::systemLoadLibrary))
196201
)
197202
.filter(entry -> entry.getValue().fromJavaVersion() == null || Runtime.version().feature() >= entry.getValue().fromJavaVersion())
198203
.collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue));

libs/entitlement/qa/entitlement-allowed-nonmodular/src/main/plugin-metadata/entitlement-policy.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ ALL-UNNAMED:
77
properties:
88
- es.entitlements.checkSetSystemProperty
99
- es.entitlements.checkClearSystemProperty
10+
- load_native_libraries

libs/entitlement/qa/entitlement-allowed/src/main/plugin-metadata/entitlement-policy.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ org.elasticsearch.entitlement.qa.common:
77
properties:
88
- es.entitlements.checkSetSystemProperty
99
- es.entitlements.checkClearSystemProperty
10+
- load_native_libraries

libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import org.elasticsearch.entitlement.runtime.policy.Entitlement;
2323
import org.elasticsearch.entitlement.runtime.policy.ExitVMEntitlement;
2424
import org.elasticsearch.entitlement.runtime.policy.InboundNetworkEntitlement;
25+
import org.elasticsearch.entitlement.runtime.policy.LoadNativeLibrariesEntitlement;
2526
import org.elasticsearch.entitlement.runtime.policy.OutboundNetworkEntitlement;
2627
import org.elasticsearch.entitlement.runtime.policy.Policy;
2728
import org.elasticsearch.entitlement.runtime.policy.PolicyManager;
@@ -92,7 +93,8 @@ private static PolicyManager createPolicyManager() {
9293
new ExitVMEntitlement(),
9394
new CreateClassLoaderEntitlement(),
9495
new InboundNetworkEntitlement(),
95-
new OutboundNetworkEntitlement()
96+
new OutboundNetworkEntitlement(),
97+
new LoadNativeLibrariesEntitlement()
9698
)
9799
),
98100
new Scope("org.apache.httpcomponents.httpclient", List.of(new OutboundNetworkEntitlement())),

libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -732,4 +732,24 @@ public ElasticsearchEntitlementChecker(PolicyManager policyManager) {
732732
public void check$sun_nio_ch_DatagramChannelImpl$receive(Class<?> callerClass, DatagramChannel that, ByteBuffer dst) {
733733
policyManager.checkInboundNetworkAccess(callerClass);
734734
}
735+
736+
@Override
737+
public void check$java_lang_Runtime$load(Class<?> callerClass, Runtime that, String filename) {
738+
policyManager.checkLoadingNativeLibraries(callerClass);
739+
}
740+
741+
@Override
742+
public void check$java_lang_Runtime$loadLibrary(Class<?> callerClass, Runtime that, String libname) {
743+
policyManager.checkLoadingNativeLibraries(callerClass);
744+
}
745+
746+
@Override
747+
public void check$java_lang_System$$load(Class<?> callerClass, String filename) {
748+
policyManager.checkLoadingNativeLibraries(callerClass);
749+
}
750+
751+
@Override
752+
public void check$java_lang_System$$loadLibrary(Class<?> callerClass, String libname) {
753+
policyManager.checkLoadingNativeLibraries(callerClass);
754+
}
735755
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the "Elastic License
4+
* 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side
5+
* Public License v 1"; you may not use this file except in compliance with, at
6+
* your election, the "Elastic License 2.0", the "GNU Affero General Public
7+
* License v3.0 only", or the "Server Side Public License, v 1".
8+
*/
9+
10+
package org.elasticsearch.entitlement.runtime.policy;
11+
12+
/**
13+
* An Entitlement to allow loading native libraries
14+
*/
15+
public record LoadNativeLibrariesEntitlement() implements Entitlement {
16+
@ExternalEntitlement(esModulesOnly = false)
17+
public LoadNativeLibrariesEntitlement {}
18+
}

libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyManager.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,13 @@ public void checkReadSensitiveNetworkInformation(Class<?> callerClass) {
189189
neverEntitled(callerClass, "access sensitive network information");
190190
}
191191

192+
/**
193+
* Check for operations that can access sensitive network information, e.g. secrets, tokens or SSL sessions
194+
*/
195+
public void checkLoadingNativeLibraries(Class<?> callerClass) {
196+
checkEntitlementPresent(callerClass, LoadNativeLibrariesEntitlement.class);
197+
}
198+
192199
private String operationDescription(String methodName) {
193200
// TODO: Use a more human-readable description. Perhaps share code with InstrumentationServiceImpl.parseCheckerMethodName
194201
return methodName.substring(methodName.indexOf('$'));

libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/policy/PolicyParser.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ public class PolicyParser {
4141
SetHttpsConnectionPropertiesEntitlement.class,
4242
OutboundNetworkEntitlement.class,
4343
InboundNetworkEntitlement.class,
44-
WriteSystemPropertiesEntitlement.class
44+
WriteSystemPropertiesEntitlement.class,
45+
LoadNativeLibrariesEntitlement.class
4546
).collect(Collectors.toUnmodifiableMap(PolicyParser::getEntitlementTypeName, Function.identity()));
4647

4748
protected final XContentParser policyParser;

0 commit comments

Comments
 (0)