|
|
@@ -29,11 +29,13 @@ import org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlemen
|
|
|
import org.elasticsearch.entitlement.runtime.policy.entitlements.InboundNetworkEntitlement;
|
|
|
import org.elasticsearch.entitlement.runtime.policy.entitlements.LoadNativeLibrariesEntitlement;
|
|
|
import org.elasticsearch.entitlement.runtime.policy.entitlements.OutboundNetworkEntitlement;
|
|
|
+import org.elasticsearch.entitlement.runtime.policy.entitlements.ReadStoreAttributesEntitlement;
|
|
|
|
|
|
import java.lang.instrument.Instrumentation;
|
|
|
import java.lang.reflect.Constructor;
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
|
import java.nio.channels.spi.SelectorProvider;
|
|
|
+import java.nio.file.FileStore;
|
|
|
import java.nio.file.FileSystems;
|
|
|
import java.nio.file.OpenOption;
|
|
|
import java.nio.file.Path;
|
|
|
@@ -46,6 +48,7 @@ import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
import java.util.stream.Collectors;
|
|
|
import java.util.stream.Stream;
|
|
|
+import java.util.stream.StreamSupport;
|
|
|
|
|
|
import static org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement.Mode.READ_WRITE;
|
|
|
|
|
|
@@ -63,6 +66,11 @@ public class EntitlementInitialization {
|
|
|
|
|
|
private static ElasticsearchEntitlementChecker manager;
|
|
|
|
|
|
+ interface InstrumentationInfoFunction {
|
|
|
+ InstrumentationService.InstrumentationInfo of(String methodName, Class<?>... parameterTypes) throws ClassNotFoundException,
|
|
|
+ NoSuchMethodException;
|
|
|
+ }
|
|
|
+
|
|
|
// Note: referenced by bridge reflectively
|
|
|
public static EntitlementChecker checker() {
|
|
|
return manager;
|
|
|
@@ -76,22 +84,26 @@ public class EntitlementInitialization {
|
|
|
|
|
|
Map<MethodKey, CheckMethod> checkMethods = new HashMap<>(INSTRUMENTATION_SERVICE.lookupMethods(latestCheckerInterface));
|
|
|
var fileSystemProviderClass = FileSystems.getDefault().provider().getClass();
|
|
|
- Stream.of(
|
|
|
- INSTRUMENTATION_SERVICE.lookupImplementationMethod(
|
|
|
- FileSystemProvider.class,
|
|
|
- "newInputStream",
|
|
|
- fileSystemProviderClass,
|
|
|
- EntitlementChecker.class,
|
|
|
- "checkNewInputStream",
|
|
|
- Path.class,
|
|
|
- OpenOption[].class
|
|
|
- ),
|
|
|
- INSTRUMENTATION_SERVICE.lookupImplementationMethod(
|
|
|
- SelectorProvider.class,
|
|
|
- "inheritedChannel",
|
|
|
- SelectorProvider.provider().getClass(),
|
|
|
- EntitlementChecker.class,
|
|
|
- "checkSelectorProviderInheritedChannel"
|
|
|
+
|
|
|
+ Stream.concat(
|
|
|
+ fileStoreChecks(),
|
|
|
+ Stream.of(
|
|
|
+ INSTRUMENTATION_SERVICE.lookupImplementationMethod(
|
|
|
+ FileSystemProvider.class,
|
|
|
+ "newInputStream",
|
|
|
+ fileSystemProviderClass,
|
|
|
+ EntitlementChecker.class,
|
|
|
+ "checkNewInputStream",
|
|
|
+ Path.class,
|
|
|
+ OpenOption[].class
|
|
|
+ ),
|
|
|
+ INSTRUMENTATION_SERVICE.lookupImplementationMethod(
|
|
|
+ SelectorProvider.class,
|
|
|
+ "inheritedChannel",
|
|
|
+ SelectorProvider.provider().getClass(),
|
|
|
+ EntitlementChecker.class,
|
|
|
+ "checkSelectorProviderInheritedChannel"
|
|
|
+ )
|
|
|
)
|
|
|
).forEach(instrumentation -> checkMethods.put(instrumentation.targetMethod(), instrumentation.checkMethod()));
|
|
|
|
|
|
@@ -126,6 +138,7 @@ public class EntitlementInitialization {
|
|
|
"org.elasticsearch.server",
|
|
|
List.of(
|
|
|
new ExitVMEntitlement(),
|
|
|
+ new ReadStoreAttributesEntitlement(),
|
|
|
new CreateClassLoaderEntitlement(),
|
|
|
new InboundNetworkEntitlement(),
|
|
|
new OutboundNetworkEntitlement(),
|
|
|
@@ -151,6 +164,45 @@ public class EntitlementInitialization {
|
|
|
return new PolicyManager(serverPolicy, agentEntitlements, pluginPolicies, resolver, AGENTS_PACKAGE_NAME, ENTITLEMENTS_MODULE);
|
|
|
}
|
|
|
|
|
|
+ private static Stream<InstrumentationService.InstrumentationInfo> fileStoreChecks() {
|
|
|
+ var fileStoreClasses = StreamSupport.stream(FileSystems.getDefault().getFileStores().spliterator(), false)
|
|
|
+ .map(FileStore::getClass)
|
|
|
+ .distinct();
|
|
|
+ return fileStoreClasses.flatMap(fileStoreClass -> {
|
|
|
+ var instrumentation = new InstrumentationInfoFunction() {
|
|
|
+ @Override
|
|
|
+ public InstrumentationService.InstrumentationInfo of(String methodName, Class<?>... parameterTypes)
|
|
|
+ throws ClassNotFoundException, NoSuchMethodException {
|
|
|
+ return INSTRUMENTATION_SERVICE.lookupImplementationMethod(
|
|
|
+ FileStore.class,
|
|
|
+ methodName,
|
|
|
+ fileStoreClass,
|
|
|
+ EntitlementChecker.class,
|
|
|
+ "check" + Character.toUpperCase(methodName.charAt(0)) + methodName.substring(1),
|
|
|
+ parameterTypes
|
|
|
+ );
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ try {
|
|
|
+ return Stream.of(
|
|
|
+ instrumentation.of("getFileStoreAttributeView", Class.class),
|
|
|
+ instrumentation.of("getAttribute", String.class),
|
|
|
+ instrumentation.of("getBlockSize"),
|
|
|
+ instrumentation.of("getTotalSpace"),
|
|
|
+ instrumentation.of("getUnallocatedSpace"),
|
|
|
+ instrumentation.of("getUsableSpace"),
|
|
|
+ instrumentation.of("isReadOnly"),
|
|
|
+ instrumentation.of("name"),
|
|
|
+ instrumentation.of("type")
|
|
|
+
|
|
|
+ );
|
|
|
+ } catch (NoSuchMethodException | ClassNotFoundException e) {
|
|
|
+ throw new RuntimeException(e);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Returns the "most recent" checker class compatible with the current runtime Java version.
|
|
|
* For checkers, we have (optionally) version specific classes, each with a prefix (e.g. Java23).
|