From b878d2082c62d4e9912180bf146b4a694a5d6296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lorenzo=20Dematt=C3=A9?= Date: Tue, 28 Jan 2025 13:08:05 +0100 Subject: [PATCH 1/4] [Entitlements] Add checks for native libraries restricted methods (#120775) --- .../bridge/EntitlementChecker.java | 66 ++++++++++ .../qa/test/RestEntitlementsCheckAction.java | 16 ++- .../qa/test/VersionSpecificNativeChecks.java | 33 +++++ .../qa/test/VersionSpecificNativeChecks.java | 118 ++++++++++++++++++ .../EntitlementInitialization.java | 4 +- .../api/ElasticsearchEntitlementChecker.java | 99 +++++++++++++++ 6 files changed, 334 insertions(+), 2 deletions(-) create mode 100644 libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNativeChecks.java create mode 100644 libs/entitlement/qa/entitlement-test-plugin/src/main22/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNativeChecks.java diff --git a/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java b/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java index d2c9541742d0a..d509763b3541d 100644 --- a/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java +++ b/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java @@ -12,6 +12,13 @@ import java.io.InputStream; import java.io.PrintStream; import java.io.PrintWriter; +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.invoke.MethodHandle; import java.net.ContentHandlerFactory; import java.net.DatagramPacket; import java.net.DatagramSocket; @@ -40,11 +47,13 @@ import java.nio.channels.DatagramChannel; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; +import java.nio.file.Path; import java.security.cert.CertStoreParameters; import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.TimeZone; +import java.util.function.Consumer; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; @@ -411,6 +420,7 @@ public interface EntitlementChecker { // // Load native libraries // + // Using the list of restricted methods from https://download.java.net/java/early_access/jdk24/docs/api/restricted-list.html void check$java_lang_Runtime$load(Class callerClass, Runtime that, String filename); void check$java_lang_Runtime$loadLibrary(Class callerClass, Runtime that, String libname); @@ -418,4 +428,60 @@ public interface EntitlementChecker { void check$java_lang_System$$load(Class callerClass, String filename); void check$java_lang_System$$loadLibrary(Class callerClass, String libname); + + // Sealed implementation of java.lang.foreign.AddressLayout + void check$jdk_internal_foreign_layout_ValueLayouts$OfAddressImpl$withTargetLayout( + Class callerClass, + AddressLayout that, + MemoryLayout memoryLayout + ); + + // Sealed implementation of java.lang.foreign.Linker + void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( + Class callerClass, + Linker that, + FunctionDescriptor function, + Linker.Option... options + ); + + void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( + Class callerClass, + Linker that, + MemorySegment address, + FunctionDescriptor function, + Linker.Option... options + ); + + void check$jdk_internal_foreign_abi_AbstractLinker$upcallStub( + Class callerClass, + Linker that, + MethodHandle target, + FunctionDescriptor function, + Arena arena, + Linker.Option... options + ); + + // Sealed implementation for java.lang.foreign.MemorySegment.reinterpret(long) + void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret(Class callerClass, MemorySegment that, long newSize); + + void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( + Class callerClass, + MemorySegment that, + long newSize, + Arena arena, + Consumer cleanup + ); + + void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( + Class callerClass, + MemorySegment that, + Arena arena, + Consumer cleanup + ); + + void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, String name, Arena arena); + + void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, Path path, Arena arena); + + void check$java_lang_ModuleLayer$Controller$enableNativeAccess(Class callerClass, ModuleLayer.Controller that, Module target); } diff --git a/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/RestEntitlementsCheckAction.java b/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/RestEntitlementsCheckAction.java index 1e754f657e260..c2b6478e561a8 100644 --- a/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/RestEntitlementsCheckAction.java +++ b/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/RestEntitlementsCheckAction.java @@ -199,7 +199,21 @@ static CheckAction alwaysDenied(CheckedRunnable action) { entry("runtime_load", forPlugins(LoadNativeLibrariesCheckActions::runtimeLoad)), entry("runtime_load_library", forPlugins(LoadNativeLibrariesCheckActions::runtimeLoadLibrary)), entry("system_load", forPlugins(LoadNativeLibrariesCheckActions::systemLoad)), - entry("system_load_library", forPlugins(LoadNativeLibrariesCheckActions::systemLoadLibrary)) + entry("system_load_library", forPlugins(LoadNativeLibrariesCheckActions::systemLoadLibrary)), + + entry("enable_native_access", new CheckAction(VersionSpecificNativeChecks::enableNativeAccess, false, 22)), + entry("address_target_layout", new CheckAction(VersionSpecificNativeChecks::addressLayoutWithTargetLayout, false, 22)), + entry("donwncall_handle", new CheckAction(VersionSpecificNativeChecks::linkerDowncallHandle, false, 22)), + entry("donwncall_handle_with_address", new CheckAction(VersionSpecificNativeChecks::linkerDowncallHandleWithAddress, false, 22)), + entry("upcall_stub", new CheckAction(VersionSpecificNativeChecks::linkerUpcallStub, false, 22)), + entry("reinterpret", new CheckAction(VersionSpecificNativeChecks::memorySegmentReinterpret, false, 22)), + entry("reinterpret_cleanup", new CheckAction(VersionSpecificNativeChecks::memorySegmentReinterpretWithCleanup, false, 22)), + entry( + "reinterpret_size_cleanup", + new CheckAction(VersionSpecificNativeChecks::memorySegmentReinterpretWithSizeAndCleanup, false, 22) + ), + entry("symbol_lookup_name", new CheckAction(VersionSpecificNativeChecks::symbolLookupWithName, false, 22)), + entry("symbol_lookup_path", new CheckAction(VersionSpecificNativeChecks::symbolLookupWithPath, false, 22)) ) .filter(entry -> entry.getValue().fromJavaVersion() == null || Runtime.version().feature() >= entry.getValue().fromJavaVersion()) .collect(Collectors.toUnmodifiableMap(Map.Entry::getKey, Map.Entry::getValue)); diff --git a/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNativeChecks.java b/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNativeChecks.java new file mode 100644 index 0000000000000..cb84c9bd9042d --- /dev/null +++ b/libs/entitlement/qa/entitlement-test-plugin/src/main/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNativeChecks.java @@ -0,0 +1,33 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +package org.elasticsearch.entitlement.qa.test; + +class VersionSpecificNativeChecks { + + static void enableNativeAccess() throws Exception {} + + static void addressLayoutWithTargetLayout() {} + + static void linkerDowncallHandle() {} + + static void linkerDowncallHandleWithAddress() {} + + static void linkerUpcallStub() throws NoSuchMethodException {} + + static void memorySegmentReinterpret() {} + + static void memorySegmentReinterpretWithCleanup() {} + + static void memorySegmentReinterpretWithSizeAndCleanup() {} + + static void symbolLookupWithPath() {} + + static void symbolLookupWithName() {} +} diff --git a/libs/entitlement/qa/entitlement-test-plugin/src/main22/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNativeChecks.java b/libs/entitlement/qa/entitlement-test-plugin/src/main22/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNativeChecks.java new file mode 100644 index 0000000000000..0a69f7255a200 --- /dev/null +++ b/libs/entitlement/qa/entitlement-test-plugin/src/main22/java/org/elasticsearch/entitlement/qa/test/VersionSpecificNativeChecks.java @@ -0,0 +1,118 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +package org.elasticsearch.entitlement.qa.test; + +import org.elasticsearch.entitlement.qa.entitled.EntitledPlugin; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.SymbolLookup; +import java.lang.foreign.ValueLayout; +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.module.Configuration; +import java.lang.module.ModuleFinder; +import java.nio.file.Path; +import java.util.List; +import java.util.Set; + +import static java.lang.foreign.ValueLayout.ADDRESS; +import static java.lang.foreign.ValueLayout.JAVA_LONG; + +class VersionSpecificNativeChecks { + + static void enableNativeAccess() throws Exception { + ModuleLayer parent = ModuleLayer.boot(); + + var location = EntitledPlugin.class.getProtectionDomain().getCodeSource().getLocation(); + + // We create a layer for our own module, so we have a controller to try and call enableNativeAccess on it. + // This works in both the modular and non-modular case: the target module has to be present in the new layer, but its entitlements + // and policies do not matter to us: we are checking that the caller is (or isn't) entitled to use enableNativeAccess + Configuration cf = parent.configuration() + .resolve(ModuleFinder.of(Path.of(location.toURI())), ModuleFinder.of(), Set.of("org.elasticsearch.entitlement.qa.entitled")); + var controller = ModuleLayer.defineModulesWithOneLoader(cf, List.of(parent), ClassLoader.getSystemClassLoader()); + var targetModule = controller.layer().findModule("org.elasticsearch.entitlement.qa.entitled"); + + controller.enableNativeAccess(targetModule.get()); + } + + static void addressLayoutWithTargetLayout() { + AddressLayout addressLayout = ADDRESS.withoutTargetLayout(); + addressLayout.withTargetLayout(MemoryLayout.sequenceLayout(Long.MAX_VALUE, ValueLayout.JAVA_BYTE)); + } + + static void linkerDowncallHandle() { + Linker linker = Linker.nativeLinker(); + linker.downcallHandle(FunctionDescriptor.of(JAVA_LONG, ADDRESS)); + } + + static void linkerDowncallHandleWithAddress() { + Linker linker = Linker.nativeLinker(); + linker.downcallHandle(linker.defaultLookup().find("strlen").get(), FunctionDescriptor.of(JAVA_LONG, ADDRESS)); + } + + static int callback() { + return 0; + } + + static void linkerUpcallStub() throws NoSuchMethodException { + Linker linker = Linker.nativeLinker(); + + MethodHandle mh = null; + try { + mh = MethodHandles.lookup().findStatic(VersionSpecificNativeChecks.class, "callback", MethodType.methodType(int.class)); + } catch (IllegalAccessException e) { + assert false; + } + + FunctionDescriptor callbackDescriptor = FunctionDescriptor.of(ValueLayout.JAVA_INT); + linker.upcallStub(mh, callbackDescriptor, Arena.ofAuto()); + } + + static void memorySegmentReinterpret() { + Arena arena = Arena.ofAuto(); + MemorySegment segment = arena.allocate(100); + segment.reinterpret(50); + } + + static void memorySegmentReinterpretWithCleanup() { + Arena arena = Arena.ofAuto(); + MemorySegment segment = arena.allocate(100); + segment.reinterpret(Arena.ofAuto(), s -> {}); + } + + static void memorySegmentReinterpretWithSizeAndCleanup() { + Arena arena = Arena.ofAuto(); + MemorySegment segment = arena.allocate(100); + segment.reinterpret(50, Arena.ofAuto(), s -> {}); + } + + static void symbolLookupWithPath() { + try { + SymbolLookup.libraryLookup(Path.of("/foo/bar/libFoo.so"), Arena.ofAuto()); + } catch (IllegalArgumentException e) { + // IllegalArgumentException is thrown if path does not point to a valid library (and it does not) + } + } + + static void symbolLookupWithName() { + try { + SymbolLookup.libraryLookup("foo", Arena.ofAuto()); + } catch (IllegalArgumentException e) { + // IllegalArgumentException is thrown if path does not point to a valid library (and it does not) + } + } +} diff --git a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java index 4ee9fd1bbca25..a8938c16955a7 100644 --- a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java +++ b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java @@ -98,7 +98,9 @@ private static PolicyManager createPolicyManager() { ) ), new Scope("org.apache.httpcomponents.httpclient", List.of(new OutboundNetworkEntitlement())), - new Scope("io.netty.transport", List.of(new InboundNetworkEntitlement(), new OutboundNetworkEntitlement())) + new Scope("io.netty.transport", List.of(new InboundNetworkEntitlement(), new OutboundNetworkEntitlement())), + new Scope("org.apache.lucene.core", List.of(new LoadNativeLibrariesEntitlement())), + new Scope("org.elasticsearch.nativeaccess", List.of(new LoadNativeLibrariesEntitlement())) ) ); // agents run without a module, so this is a special hack for the apm agent diff --git a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java index 55adbf45699ab..8600dd357c384 100644 --- a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java +++ b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java @@ -15,6 +15,13 @@ import java.io.InputStream; import java.io.PrintStream; import java.io.PrintWriter; +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.invoke.MethodHandle; import java.net.ContentHandlerFactory; import java.net.DatagramPacket; import java.net.DatagramSocket; @@ -44,11 +51,13 @@ import java.nio.channels.DatagramChannel; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; +import java.nio.file.Path; import java.security.cert.CertStoreParameters; import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.TimeZone; +import java.util.function.Consumer; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; @@ -752,6 +761,7 @@ public ElasticsearchEntitlementChecker(PolicyManager policyManager) { @Override public void check$java_lang_Runtime$load(Class callerClass, Runtime that, String filename) { + // TODO: check filesystem entitlement READ policyManager.checkLoadingNativeLibraries(callerClass); } @@ -762,6 +772,7 @@ public ElasticsearchEntitlementChecker(PolicyManager policyManager) { @Override public void check$java_lang_System$$load(Class callerClass, String filename) { + // TODO: check filesystem entitlement READ policyManager.checkLoadingNativeLibraries(callerClass); } @@ -769,4 +780,92 @@ public ElasticsearchEntitlementChecker(PolicyManager policyManager) { public void check$java_lang_System$$loadLibrary(Class callerClass, String libname) { policyManager.checkLoadingNativeLibraries(callerClass); } + + @Override + public void check$jdk_internal_foreign_layout_ValueLayouts$OfAddressImpl$withTargetLayout( + Class callerClass, + AddressLayout that, + MemoryLayout memoryLayout + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( + Class callerClass, + Linker that, + FunctionDescriptor function, + Linker.Option... options + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( + Class callerClass, + Linker that, + MemorySegment address, + FunctionDescriptor function, + Linker.Option... options + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_abi_AbstractLinker$upcallStub( + Class callerClass, + Linker that, + MethodHandle target, + FunctionDescriptor function, + Arena arena, + Linker.Option... options + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret(Class callerClass, MemorySegment that, long newSize) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( + Class callerClass, + MemorySegment that, + long newSize, + Arena arena, + Consumer cleanup + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( + Class callerClass, + MemorySegment that, + Arena arena, + Consumer cleanup + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, String name, Arena arena) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, Path path, Arena arena) { + // TODO: check filesystem entitlement READ + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$java_lang_ModuleLayer$Controller$enableNativeAccess( + Class callerClass, + ModuleLayer.Controller that, + Module target + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } } From edbb2937321d0aea55939f6c1ec662ca4ff59291 Mon Sep 17 00:00:00 2001 From: Lorenzo Dematte Date: Tue, 28 Jan 2025 16:27:08 +0100 Subject: [PATCH 2/4] Introducing main21 (does not compile with main23 on the main lib) --- libs/entitlement/bridge/build.gradle | 3 + .../bridge/EntitlementChecker.java | 63 ---------- .../bridge/Java21EntitlementChecker.java | 76 ++++++++++++ .../Java21EntitlementCheckerHandle.java | 27 +++++ libs/entitlement/build.gradle | 3 + .../api/ElasticsearchEntitlementChecker.java | 90 +-------------- ...Java21ElasticsearchEntitlementChecker.java | 109 ++++++++++++++++++ 7 files changed, 219 insertions(+), 152 deletions(-) create mode 100644 libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementChecker.java create mode 100644 libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementCheckerHandle.java create mode 100644 libs/entitlement/src/main21/java/org/elasticsearch/entitlement/runtime/api/Java21ElasticsearchEntitlementChecker.java diff --git a/libs/entitlement/bridge/build.gradle b/libs/entitlement/bridge/build.gradle index a9f8f6e3a3b0a..2c69015beff39 100644 --- a/libs/entitlement/bridge/build.gradle +++ b/libs/entitlement/bridge/build.gradle @@ -17,6 +17,9 @@ tasks.named('jar').configure { if (sourceSets.findByName("main23")) { from sourceSets.main23.output } + if (sourceSets.findByName("main21")) { + from sourceSets.main21.output + } } tasks.withType(CheckForbiddenApisTask).configureEach { diff --git a/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java b/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java index d509763b3541d..05813afcdfa18 100644 --- a/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java +++ b/libs/entitlement/bridge/src/main/java/org/elasticsearch/entitlement/bridge/EntitlementChecker.java @@ -12,13 +12,6 @@ import java.io.InputStream; import java.io.PrintStream; import java.io.PrintWriter; -import java.lang.foreign.AddressLayout; -import java.lang.foreign.Arena; -import java.lang.foreign.FunctionDescriptor; -import java.lang.foreign.Linker; -import java.lang.foreign.MemoryLayout; -import java.lang.foreign.MemorySegment; -import java.lang.invoke.MethodHandle; import java.net.ContentHandlerFactory; import java.net.DatagramPacket; import java.net.DatagramSocket; @@ -47,13 +40,11 @@ import java.nio.channels.DatagramChannel; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; -import java.nio.file.Path; import java.security.cert.CertStoreParameters; import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.TimeZone; -import java.util.function.Consumer; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; @@ -429,59 +420,5 @@ public interface EntitlementChecker { void check$java_lang_System$$loadLibrary(Class callerClass, String libname); - // Sealed implementation of java.lang.foreign.AddressLayout - void check$jdk_internal_foreign_layout_ValueLayouts$OfAddressImpl$withTargetLayout( - Class callerClass, - AddressLayout that, - MemoryLayout memoryLayout - ); - - // Sealed implementation of java.lang.foreign.Linker - void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( - Class callerClass, - Linker that, - FunctionDescriptor function, - Linker.Option... options - ); - - void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( - Class callerClass, - Linker that, - MemorySegment address, - FunctionDescriptor function, - Linker.Option... options - ); - - void check$jdk_internal_foreign_abi_AbstractLinker$upcallStub( - Class callerClass, - Linker that, - MethodHandle target, - FunctionDescriptor function, - Arena arena, - Linker.Option... options - ); - - // Sealed implementation for java.lang.foreign.MemorySegment.reinterpret(long) - void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret(Class callerClass, MemorySegment that, long newSize); - - void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( - Class callerClass, - MemorySegment that, - long newSize, - Arena arena, - Consumer cleanup - ); - - void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( - Class callerClass, - MemorySegment that, - Arena arena, - Consumer cleanup - ); - - void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, String name, Arena arena); - - void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, Path path, Arena arena); - void check$java_lang_ModuleLayer$Controller$enableNativeAccess(Class callerClass, ModuleLayer.Controller that, Module target); } diff --git a/libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementChecker.java b/libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementChecker.java new file mode 100644 index 0000000000000..c347b6dcc56e9 --- /dev/null +++ b/libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementChecker.java @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +package org.elasticsearch.entitlement.bridge; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.invoke.MethodHandle; +import java.nio.file.Path; +import java.util.function.Consumer; + +public interface Java21EntitlementChecker extends EntitlementChecker { + // Sealed implementation of java.lang.foreign.AddressLayout + void check$jdk_internal_foreign_layout_ValueLayouts$OfAddressImpl$withTargetLayout( + Class callerClass, + AddressLayout that, + MemoryLayout memoryLayout + ); + + // Sealed implementation of java.lang.foreign.Linker + void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( + Class callerClass, + Linker that, + FunctionDescriptor function, + Linker.Option... options + ); + + void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( + Class callerClass, + Linker that, + MemorySegment address, + FunctionDescriptor function, + Linker.Option... options + ); + + void check$jdk_internal_foreign_abi_AbstractLinker$upcallStub( + Class callerClass, + Linker that, + MethodHandle target, + FunctionDescriptor function, + Arena arena, + Linker.Option... options + ); + + // Sealed implementation for java.lang.foreign.MemorySegment.reinterpret(long) + void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret(Class callerClass, MemorySegment that, long newSize); + + void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( + Class callerClass, + MemorySegment that, + long newSize, + Arena arena, + Consumer cleanup + ); + + void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( + Class callerClass, + MemorySegment that, + Arena arena, + Consumer cleanup + ); + + void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, String name, Arena arena); + + void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, Path path, Arena arena); +} diff --git a/libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementCheckerHandle.java b/libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementCheckerHandle.java new file mode 100644 index 0000000000000..51bead10a779b --- /dev/null +++ b/libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementCheckerHandle.java @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +package org.elasticsearch.entitlement.bridge; + +/** + * Java21 variant of {@link EntitlementChecker} handle holder. + */ +public class Java21EntitlementCheckerHandle { + + public static Java21EntitlementChecker instance() { + return Holder.instance; + } + + private static class Holder { + private static final Java21EntitlementChecker instance = HandleLoader.load(Java21EntitlementChecker.class); + } + + // no construction + private Java21EntitlementCheckerHandle() {} +} diff --git a/libs/entitlement/build.gradle b/libs/entitlement/build.gradle index 841591873153c..c7fff22421376 100644 --- a/libs/entitlement/build.gradle +++ b/libs/entitlement/build.gradle @@ -28,6 +28,9 @@ dependencies { } // guarding for intellij + if (sourceSets.findByName("main21")) { + main21CompileOnly project(path: ':libs:entitlement:bridge', configuration: 'java21') + } if (sourceSets.findByName("main23")) { main23CompileOnly project(path: ':libs:entitlement:bridge', configuration: 'java23') } diff --git a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java index 8600dd357c384..2807c1a43ccdd 100644 --- a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java +++ b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/runtime/api/ElasticsearchEntitlementChecker.java @@ -15,13 +15,6 @@ import java.io.InputStream; import java.io.PrintStream; import java.io.PrintWriter; -import java.lang.foreign.AddressLayout; -import java.lang.foreign.Arena; -import java.lang.foreign.FunctionDescriptor; -import java.lang.foreign.Linker; -import java.lang.foreign.MemoryLayout; -import java.lang.foreign.MemorySegment; -import java.lang.invoke.MethodHandle; import java.net.ContentHandlerFactory; import java.net.DatagramPacket; import java.net.DatagramSocket; @@ -51,13 +44,11 @@ import java.nio.channels.DatagramChannel; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; -import java.nio.file.Path; import java.security.cert.CertStoreParameters; import java.util.List; import java.util.Locale; import java.util.Properties; import java.util.TimeZone; -import java.util.function.Consumer; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; @@ -71,7 +62,7 @@ */ public class ElasticsearchEntitlementChecker implements EntitlementChecker { - private final PolicyManager policyManager; + protected final PolicyManager policyManager; public ElasticsearchEntitlementChecker(PolicyManager policyManager) { this.policyManager = policyManager; @@ -781,85 +772,6 @@ public ElasticsearchEntitlementChecker(PolicyManager policyManager) { policyManager.checkLoadingNativeLibraries(callerClass); } - @Override - public void check$jdk_internal_foreign_layout_ValueLayouts$OfAddressImpl$withTargetLayout( - Class callerClass, - AddressLayout that, - MemoryLayout memoryLayout - ) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( - Class callerClass, - Linker that, - FunctionDescriptor function, - Linker.Option... options - ) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( - Class callerClass, - Linker that, - MemorySegment address, - FunctionDescriptor function, - Linker.Option... options - ) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$jdk_internal_foreign_abi_AbstractLinker$upcallStub( - Class callerClass, - Linker that, - MethodHandle target, - FunctionDescriptor function, - Arena arena, - Linker.Option... options - ) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret(Class callerClass, MemorySegment that, long newSize) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( - Class callerClass, - MemorySegment that, - long newSize, - Arena arena, - Consumer cleanup - ) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( - Class callerClass, - MemorySegment that, - Arena arena, - Consumer cleanup - ) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, String name, Arena arena) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, Path path, Arena arena) { - // TODO: check filesystem entitlement READ - policyManager.checkLoadingNativeLibraries(callerClass); - } - @Override public void check$java_lang_ModuleLayer$Controller$enableNativeAccess( Class callerClass, diff --git a/libs/entitlement/src/main21/java/org/elasticsearch/entitlement/runtime/api/Java21ElasticsearchEntitlementChecker.java b/libs/entitlement/src/main21/java/org/elasticsearch/entitlement/runtime/api/Java21ElasticsearchEntitlementChecker.java new file mode 100644 index 0000000000000..a5fcdb2b14548 --- /dev/null +++ b/libs/entitlement/src/main21/java/org/elasticsearch/entitlement/runtime/api/Java21ElasticsearchEntitlementChecker.java @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +package org.elasticsearch.entitlement.runtime.api; + +import org.elasticsearch.entitlement.bridge.Java21EntitlementChecker; +import org.elasticsearch.entitlement.runtime.policy.PolicyManager; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.invoke.MethodHandle; +import java.nio.file.Path; +import java.util.function.Consumer; + +public class Java21ElasticsearchEntitlementChecker extends ElasticsearchEntitlementChecker implements Java21EntitlementChecker { + + public Java21ElasticsearchEntitlementChecker(PolicyManager policyManager) { + super(policyManager); + } + + @Override + public void check$jdk_internal_foreign_layout_ValueLayouts$OfAddressImpl$withTargetLayout( + Class callerClass, + AddressLayout that, + MemoryLayout memoryLayout + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( + Class callerClass, + Linker that, + FunctionDescriptor function, + Linker.Option... options + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( + Class callerClass, + Linker that, + MemorySegment address, + FunctionDescriptor function, + Linker.Option... options + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_abi_AbstractLinker$upcallStub( + Class callerClass, + Linker that, + MethodHandle target, + FunctionDescriptor function, + Arena arena, + Linker.Option... options + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret(Class callerClass, MemorySegment that, long newSize) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( + Class callerClass, + MemorySegment that, + long newSize, + Arena arena, + Consumer cleanup + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( + Class callerClass, + MemorySegment that, + Arena arena, + Consumer cleanup + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, String name, Arena arena) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, Path path, Arena arena) { + // TODO: check filesystem entitlement READ + policyManager.checkLoadingNativeLibraries(callerClass); + } +} From c9b6cd8486f8a8a505c7f14ad4c97d0ad04196ea Mon Sep 17 00:00:00 2001 From: Lorenzo Dematte Date: Wed, 29 Jan 2025 09:02:56 +0100 Subject: [PATCH 3/4] Move foreign API to Java22; fix EntitlementInitialization to work across multiple versions --- .../gradle/internal/MrjarPlugin.java | 1 + libs/entitlement/bridge/build.gradle | 3 + .../bridge/Java21EntitlementChecker.java | 53 --------- .../bridge/Java22EntitlementChecker.java | 76 ++++++++++++ .../Java22EntitlementCheckerHandle.java | 27 +++++ .../bridge/Java23EntitlementChecker.java | 2 +- libs/entitlement/build.gradle | 3 + .../EntitlementInitialization.java | 59 +++++++--- ...Java21ElasticsearchEntitlementChecker.java | 79 ------------- ...Java22ElasticsearchEntitlementChecker.java | 109 ++++++++++++++++++ ...Java23ElasticsearchEntitlementChecker.java | 2 +- 11 files changed, 264 insertions(+), 150 deletions(-) create mode 100644 libs/entitlement/bridge/src/main22/java/org/elasticsearch/entitlement/bridge/Java22EntitlementChecker.java create mode 100644 libs/entitlement/bridge/src/main22/java/org/elasticsearch/entitlement/bridge/Java22EntitlementCheckerHandle.java create mode 100644 libs/entitlement/src/main22/java/org/elasticsearch/entitlement/runtime/api/Java22ElasticsearchEntitlementChecker.java diff --git a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/MrjarPlugin.java b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/MrjarPlugin.java index 0d58f80363330..a14223b73018b 100644 --- a/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/MrjarPlugin.java +++ b/build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/MrjarPlugin.java @@ -154,6 +154,7 @@ private void addJar(Project project, SourceSet sourceSet, int javaVersion) { project.getConfigurations().register("java" + javaVersion); TaskProvider jarTask = project.getTasks().register("java" + javaVersion + "Jar", Jar.class, task -> { task.from(sourceSet.getOutput()); + task.getArchiveClassifier().set("java" + javaVersion); }); project.getArtifacts().add("java" + javaVersion, jarTask); } diff --git a/libs/entitlement/bridge/build.gradle b/libs/entitlement/bridge/build.gradle index 2c69015beff39..b108032a5512a 100644 --- a/libs/entitlement/bridge/build.gradle +++ b/libs/entitlement/bridge/build.gradle @@ -20,6 +20,9 @@ tasks.named('jar').configure { if (sourceSets.findByName("main21")) { from sourceSets.main21.output } + if (sourceSets.findByName("main22")) { + from sourceSets.main22.output + } } tasks.withType(CheckForbiddenApisTask).configureEach { diff --git a/libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementChecker.java b/libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementChecker.java index c347b6dcc56e9..b85bbc0196254 100644 --- a/libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementChecker.java +++ b/libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementChecker.java @@ -20,57 +20,4 @@ import java.util.function.Consumer; public interface Java21EntitlementChecker extends EntitlementChecker { - // Sealed implementation of java.lang.foreign.AddressLayout - void check$jdk_internal_foreign_layout_ValueLayouts$OfAddressImpl$withTargetLayout( - Class callerClass, - AddressLayout that, - MemoryLayout memoryLayout - ); - - // Sealed implementation of java.lang.foreign.Linker - void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( - Class callerClass, - Linker that, - FunctionDescriptor function, - Linker.Option... options - ); - - void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( - Class callerClass, - Linker that, - MemorySegment address, - FunctionDescriptor function, - Linker.Option... options - ); - - void check$jdk_internal_foreign_abi_AbstractLinker$upcallStub( - Class callerClass, - Linker that, - MethodHandle target, - FunctionDescriptor function, - Arena arena, - Linker.Option... options - ); - - // Sealed implementation for java.lang.foreign.MemorySegment.reinterpret(long) - void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret(Class callerClass, MemorySegment that, long newSize); - - void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( - Class callerClass, - MemorySegment that, - long newSize, - Arena arena, - Consumer cleanup - ); - - void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( - Class callerClass, - MemorySegment that, - Arena arena, - Consumer cleanup - ); - - void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, String name, Arena arena); - - void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, Path path, Arena arena); } diff --git a/libs/entitlement/bridge/src/main22/java/org/elasticsearch/entitlement/bridge/Java22EntitlementChecker.java b/libs/entitlement/bridge/src/main22/java/org/elasticsearch/entitlement/bridge/Java22EntitlementChecker.java new file mode 100644 index 0000000000000..13e581c16a4fb --- /dev/null +++ b/libs/entitlement/bridge/src/main22/java/org/elasticsearch/entitlement/bridge/Java22EntitlementChecker.java @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +package org.elasticsearch.entitlement.bridge; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.invoke.MethodHandle; +import java.nio.file.Path; +import java.util.function.Consumer; + +public interface Java22EntitlementChecker extends Java21EntitlementChecker { + // Sealed implementation of java.lang.foreign.AddressLayout + void check$jdk_internal_foreign_layout_ValueLayouts$OfAddressImpl$withTargetLayout( + Class callerClass, + AddressLayout that, + MemoryLayout memoryLayout + ); + + // Sealed implementation of java.lang.foreign.Linker + void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( + Class callerClass, + Linker that, + FunctionDescriptor function, + Linker.Option... options + ); + + void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( + Class callerClass, + Linker that, + MemorySegment address, + FunctionDescriptor function, + Linker.Option... options + ); + + void check$jdk_internal_foreign_abi_AbstractLinker$upcallStub( + Class callerClass, + Linker that, + MethodHandle target, + FunctionDescriptor function, + Arena arena, + Linker.Option... options + ); + + // Sealed implementation for java.lang.foreign.MemorySegment.reinterpret(long) + void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret(Class callerClass, MemorySegment that, long newSize); + + void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( + Class callerClass, + MemorySegment that, + long newSize, + Arena arena, + Consumer cleanup + ); + + void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( + Class callerClass, + MemorySegment that, + Arena arena, + Consumer cleanup + ); + + void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, String name, Arena arena); + + void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, Path path, Arena arena); +} diff --git a/libs/entitlement/bridge/src/main22/java/org/elasticsearch/entitlement/bridge/Java22EntitlementCheckerHandle.java b/libs/entitlement/bridge/src/main22/java/org/elasticsearch/entitlement/bridge/Java22EntitlementCheckerHandle.java new file mode 100644 index 0000000000000..dcd1dbc6bac60 --- /dev/null +++ b/libs/entitlement/bridge/src/main22/java/org/elasticsearch/entitlement/bridge/Java22EntitlementCheckerHandle.java @@ -0,0 +1,27 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +package org.elasticsearch.entitlement.bridge; + +/** + * Java22 variant of {@link EntitlementChecker} handle holder. + */ +public class Java22EntitlementCheckerHandle { + + public static Java22EntitlementChecker instance() { + return Holder.instance; + } + + private static class Holder { + private static final Java22EntitlementChecker instance = HandleLoader.load(Java22EntitlementChecker.class); + } + + // no construction + private Java22EntitlementCheckerHandle() {} +} diff --git a/libs/entitlement/bridge/src/main23/java/org/elasticsearch/entitlement/bridge/Java23EntitlementChecker.java b/libs/entitlement/bridge/src/main23/java/org/elasticsearch/entitlement/bridge/Java23EntitlementChecker.java index 244632e80ffa0..a02533e16f840 100644 --- a/libs/entitlement/bridge/src/main23/java/org/elasticsearch/entitlement/bridge/Java23EntitlementChecker.java +++ b/libs/entitlement/bridge/src/main23/java/org/elasticsearch/entitlement/bridge/Java23EntitlementChecker.java @@ -9,4 +9,4 @@ package org.elasticsearch.entitlement.bridge; -public interface Java23EntitlementChecker extends EntitlementChecker {} +public interface Java23EntitlementChecker extends Java22EntitlementChecker {} diff --git a/libs/entitlement/build.gradle b/libs/entitlement/build.gradle index c7fff22421376..b221851a5b020 100644 --- a/libs/entitlement/build.gradle +++ b/libs/entitlement/build.gradle @@ -31,6 +31,9 @@ dependencies { if (sourceSets.findByName("main21")) { main21CompileOnly project(path: ':libs:entitlement:bridge', configuration: 'java21') } + if (sourceSets.findByName("main22")) { + main22CompileOnly project(path: ':libs:entitlement:bridge', configuration: 'java22') + } if (sourceSets.findByName("main23")) { main23CompileOnly project(path: ':libs:entitlement:bridge', configuration: 'java23') } diff --git a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java index a8938c16955a7..a9f1cc8624f0a 100644 --- a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java +++ b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java @@ -32,6 +32,8 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; @@ -59,11 +61,21 @@ public static EntitlementChecker checker() { public static void initialize(Instrumentation inst) throws Exception { manager = initChecker(); - Map checkMethods = INSTRUMENTER_FACTORY.lookupMethods(EntitlementChecker.class); + Map checkMethods = new HashMap<>(); + int javaVersion = Runtime.version().feature(); + Set> interfaces = new HashSet<>(); + for (int i = 17; i <= javaVersion; ++ i) { + interfaces.add(getVersionSpecificCheckerClass(i, "org.elasticsearch.entitlement.bridge", "EntitlementChecker")); + } + for (var checkerInterface: interfaces) { + checkMethods.putAll(INSTRUMENTER_FACTORY.lookupMethods(checkerInterface)); + } + var latestCheckerInterface = getVersionSpecificCheckerClass( + javaVersion, "org.elasticsearch.entitlement.bridge", "EntitlementChecker"); var classesToTransform = checkMethods.keySet().stream().map(MethodKey::className).collect(Collectors.toSet()); - Instrumenter instrumenter = INSTRUMENTER_FACTORY.newInstrumenter(EntitlementChecker.class, checkMethods); + Instrumenter instrumenter = INSTRUMENTER_FACTORY.newInstrumenter(latestCheckerInterface, checkMethods); inst.addTransformer(new Transformer(instrumenter, classesToTransform), true); inst.retransformClasses(findClassesToRetransform(inst.getAllLoadedClasses(), classesToTransform)); } @@ -113,20 +125,11 @@ private static PolicyManager createPolicyManager() { private static ElasticsearchEntitlementChecker initChecker() { final PolicyManager policyManager = createPolicyManager(); - int javaVersion = Runtime.version().feature(); - final String classNamePrefix; - if (javaVersion >= 23) { - classNamePrefix = "Java23"; - } else { - classNamePrefix = ""; - } - final String className = "org.elasticsearch.entitlement.runtime.api." + classNamePrefix + "ElasticsearchEntitlementChecker"; - Class clazz; - try { - clazz = Class.forName(className); - } catch (ClassNotFoundException e) { - throw new AssertionError("entitlement lib cannot find entitlement impl", e); - } + Class clazz = getVersionSpecificCheckerClass( + Runtime.version().feature(), + "org.elasticsearch.entitlement.runtime.api", + "ElasticsearchEntitlementChecker" + ); Constructor constructor; try { constructor = clazz.getConstructor(PolicyManager.class); @@ -140,6 +143,30 @@ private static ElasticsearchEntitlementChecker initChecker() { } } + private static Class getVersionSpecificCheckerClass(int javaVersion, String packageName, String baseClassName) { + final String classNamePrefix; + if (javaVersion == 21) { + classNamePrefix = "Java21"; + } + else if (javaVersion == 22) { + classNamePrefix = "Java22"; + } + else if (javaVersion >= 23) { + classNamePrefix = "Java23"; + } + else { + classNamePrefix = ""; + } + final String className = packageName + "." + classNamePrefix + baseClassName; + Class clazz; + try { + clazz = Class.forName(className); + } catch (ClassNotFoundException e) { + throw new AssertionError("entitlement lib cannot find entitlement class " + className, e); + } + return clazz; + } + private static final InstrumentationService INSTRUMENTER_FACTORY = new ProviderLocator<>( "entitlement", InstrumentationService.class, diff --git a/libs/entitlement/src/main21/java/org/elasticsearch/entitlement/runtime/api/Java21ElasticsearchEntitlementChecker.java b/libs/entitlement/src/main21/java/org/elasticsearch/entitlement/runtime/api/Java21ElasticsearchEntitlementChecker.java index a5fcdb2b14548..5c6614831d8f0 100644 --- a/libs/entitlement/src/main21/java/org/elasticsearch/entitlement/runtime/api/Java21ElasticsearchEntitlementChecker.java +++ b/libs/entitlement/src/main21/java/org/elasticsearch/entitlement/runtime/api/Java21ElasticsearchEntitlementChecker.java @@ -27,83 +27,4 @@ public class Java21ElasticsearchEntitlementChecker extends ElasticsearchEntitlem public Java21ElasticsearchEntitlementChecker(PolicyManager policyManager) { super(policyManager); } - - @Override - public void check$jdk_internal_foreign_layout_ValueLayouts$OfAddressImpl$withTargetLayout( - Class callerClass, - AddressLayout that, - MemoryLayout memoryLayout - ) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( - Class callerClass, - Linker that, - FunctionDescriptor function, - Linker.Option... options - ) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( - Class callerClass, - Linker that, - MemorySegment address, - FunctionDescriptor function, - Linker.Option... options - ) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$jdk_internal_foreign_abi_AbstractLinker$upcallStub( - Class callerClass, - Linker that, - MethodHandle target, - FunctionDescriptor function, - Arena arena, - Linker.Option... options - ) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret(Class callerClass, MemorySegment that, long newSize) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( - Class callerClass, - MemorySegment that, - long newSize, - Arena arena, - Consumer cleanup - ) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( - Class callerClass, - MemorySegment that, - Arena arena, - Consumer cleanup - ) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, String name, Arena arena) { - policyManager.checkLoadingNativeLibraries(callerClass); - } - - @Override - public void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, Path path, Arena arena) { - // TODO: check filesystem entitlement READ - policyManager.checkLoadingNativeLibraries(callerClass); - } } diff --git a/libs/entitlement/src/main22/java/org/elasticsearch/entitlement/runtime/api/Java22ElasticsearchEntitlementChecker.java b/libs/entitlement/src/main22/java/org/elasticsearch/entitlement/runtime/api/Java22ElasticsearchEntitlementChecker.java new file mode 100644 index 0000000000000..2fe8988a54822 --- /dev/null +++ b/libs/entitlement/src/main22/java/org/elasticsearch/entitlement/runtime/api/Java22ElasticsearchEntitlementChecker.java @@ -0,0 +1,109 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the "Elastic License + * 2.0", the "GNU Affero General Public License v3.0 only", and the "Server Side + * Public License v 1"; you may not use this file except in compliance with, at + * your election, the "Elastic License 2.0", the "GNU Affero General Public + * License v3.0 only", or the "Server Side Public License, v 1". + */ + +package org.elasticsearch.entitlement.runtime.api; + +import org.elasticsearch.entitlement.bridge.Java22EntitlementChecker; +import org.elasticsearch.entitlement.runtime.policy.PolicyManager; + +import java.lang.foreign.AddressLayout; +import java.lang.foreign.Arena; +import java.lang.foreign.FunctionDescriptor; +import java.lang.foreign.Linker; +import java.lang.foreign.MemoryLayout; +import java.lang.foreign.MemorySegment; +import java.lang.invoke.MethodHandle; +import java.nio.file.Path; +import java.util.function.Consumer; + +public class Java22ElasticsearchEntitlementChecker extends Java21ElasticsearchEntitlementChecker implements Java22EntitlementChecker { + + public Java22ElasticsearchEntitlementChecker(PolicyManager policyManager) { + super(policyManager); + } + + @Override + public void check$jdk_internal_foreign_layout_ValueLayouts$OfAddressImpl$withTargetLayout( + Class callerClass, + AddressLayout that, + MemoryLayout memoryLayout + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( + Class callerClass, + Linker that, + FunctionDescriptor function, + Linker.Option... options + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_abi_AbstractLinker$downcallHandle( + Class callerClass, + Linker that, + MemorySegment address, + FunctionDescriptor function, + Linker.Option... options + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_abi_AbstractLinker$upcallStub( + Class callerClass, + Linker that, + MethodHandle target, + FunctionDescriptor function, + Arena arena, + Linker.Option... options + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret(Class callerClass, MemorySegment that, long newSize) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( + Class callerClass, + MemorySegment that, + long newSize, + Arena arena, + Consumer cleanup + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$jdk_internal_foreign_AbstractMemorySegmentImpl$reinterpret( + Class callerClass, + MemorySegment that, + Arena arena, + Consumer cleanup + ) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, String name, Arena arena) { + policyManager.checkLoadingNativeLibraries(callerClass); + } + + @Override + public void check$java_lang_foreign_SymbolLookup$$libraryLookup(Class callerClass, Path path, Arena arena) { + // TODO: check filesystem entitlement READ + policyManager.checkLoadingNativeLibraries(callerClass); + } +} diff --git a/libs/entitlement/src/main23/java/org/elasticsearch/entitlement/runtime/api/Java23ElasticsearchEntitlementChecker.java b/libs/entitlement/src/main23/java/org/elasticsearch/entitlement/runtime/api/Java23ElasticsearchEntitlementChecker.java index 706a6649de329..0e2cc0bf94f41 100644 --- a/libs/entitlement/src/main23/java/org/elasticsearch/entitlement/runtime/api/Java23ElasticsearchEntitlementChecker.java +++ b/libs/entitlement/src/main23/java/org/elasticsearch/entitlement/runtime/api/Java23ElasticsearchEntitlementChecker.java @@ -12,7 +12,7 @@ import org.elasticsearch.entitlement.bridge.Java23EntitlementChecker; import org.elasticsearch.entitlement.runtime.policy.PolicyManager; -public class Java23ElasticsearchEntitlementChecker extends ElasticsearchEntitlementChecker implements Java23EntitlementChecker { +public class Java23ElasticsearchEntitlementChecker extends Java22ElasticsearchEntitlementChecker implements Java23EntitlementChecker { public Java23ElasticsearchEntitlementChecker(PolicyManager policyManager) { super(policyManager); From 8725b9806fa0fb49dbc14eb40d2d774a9c072532 Mon Sep 17 00:00:00 2001 From: elasticsearchmachine Date: Wed, 29 Jan 2025 08:11:15 +0000 Subject: [PATCH 4/4] [CI] Auto commit changes from spotless --- .../bridge/Java21EntitlementChecker.java | 13 +------------ .../EntitlementInitialization.java | 18 +++++++++--------- .../Java21ElasticsearchEntitlementChecker.java | 10 ---------- 3 files changed, 10 insertions(+), 31 deletions(-) diff --git a/libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementChecker.java b/libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementChecker.java index b85bbc0196254..e6add521d7229 100644 --- a/libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementChecker.java +++ b/libs/entitlement/bridge/src/main21/java/org/elasticsearch/entitlement/bridge/Java21EntitlementChecker.java @@ -9,15 +9,4 @@ package org.elasticsearch.entitlement.bridge; -import java.lang.foreign.AddressLayout; -import java.lang.foreign.Arena; -import java.lang.foreign.FunctionDescriptor; -import java.lang.foreign.Linker; -import java.lang.foreign.MemoryLayout; -import java.lang.foreign.MemorySegment; -import java.lang.invoke.MethodHandle; -import java.nio.file.Path; -import java.util.function.Consumer; - -public interface Java21EntitlementChecker extends EntitlementChecker { -} +public interface Java21EntitlementChecker extends EntitlementChecker {} diff --git a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java index a9f1cc8624f0a..82a10ccedaaa3 100644 --- a/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java +++ b/libs/entitlement/src/main/java/org/elasticsearch/entitlement/initialization/EntitlementInitialization.java @@ -64,15 +64,18 @@ public static void initialize(Instrumentation inst) throws Exception { Map checkMethods = new HashMap<>(); int javaVersion = Runtime.version().feature(); Set> interfaces = new HashSet<>(); - for (int i = 17; i <= javaVersion; ++ i) { + for (int i = 17; i <= javaVersion; ++i) { interfaces.add(getVersionSpecificCheckerClass(i, "org.elasticsearch.entitlement.bridge", "EntitlementChecker")); } - for (var checkerInterface: interfaces) { + for (var checkerInterface : interfaces) { checkMethods.putAll(INSTRUMENTER_FACTORY.lookupMethods(checkerInterface)); } var latestCheckerInterface = getVersionSpecificCheckerClass( - javaVersion, "org.elasticsearch.entitlement.bridge", "EntitlementChecker"); + javaVersion, + "org.elasticsearch.entitlement.bridge", + "EntitlementChecker" + ); var classesToTransform = checkMethods.keySet().stream().map(MethodKey::className).collect(Collectors.toSet()); Instrumenter instrumenter = INSTRUMENTER_FACTORY.newInstrumenter(latestCheckerInterface, checkMethods); @@ -147,14 +150,11 @@ private static Class getVersionSpecificCheckerClass(int javaVersion, String p final String classNamePrefix; if (javaVersion == 21) { classNamePrefix = "Java21"; - } - else if (javaVersion == 22) { + } else if (javaVersion == 22) { classNamePrefix = "Java22"; - } - else if (javaVersion >= 23) { + } else if (javaVersion >= 23) { classNamePrefix = "Java23"; - } - else { + } else { classNamePrefix = ""; } final String className = packageName + "." + classNamePrefix + baseClassName; diff --git a/libs/entitlement/src/main21/java/org/elasticsearch/entitlement/runtime/api/Java21ElasticsearchEntitlementChecker.java b/libs/entitlement/src/main21/java/org/elasticsearch/entitlement/runtime/api/Java21ElasticsearchEntitlementChecker.java index 5c6614831d8f0..ecb830daf2f61 100644 --- a/libs/entitlement/src/main21/java/org/elasticsearch/entitlement/runtime/api/Java21ElasticsearchEntitlementChecker.java +++ b/libs/entitlement/src/main21/java/org/elasticsearch/entitlement/runtime/api/Java21ElasticsearchEntitlementChecker.java @@ -12,16 +12,6 @@ import org.elasticsearch.entitlement.bridge.Java21EntitlementChecker; import org.elasticsearch.entitlement.runtime.policy.PolicyManager; -import java.lang.foreign.AddressLayout; -import java.lang.foreign.Arena; -import java.lang.foreign.FunctionDescriptor; -import java.lang.foreign.Linker; -import java.lang.foreign.MemoryLayout; -import java.lang.foreign.MemorySegment; -import java.lang.invoke.MethodHandle; -import java.nio.file.Path; -import java.util.function.Consumer; - public class Java21ElasticsearchEntitlementChecker extends ElasticsearchEntitlementChecker implements Java21EntitlementChecker { public Java21ElasticsearchEntitlementChecker(PolicyManager policyManager) {