mirror of
https://github.com/elastic/elasticsearch.git
synced 2025-06-28 09:28:55 -04:00
Check hidden frames in entitlements (#127877)
Entitlements do a stack walk to find the calling class. When method refences are used in a lambda, the frame ends up hidden in the stack walk. In the case of using a method reference with AccessController.doPrivileged, the call looks like it is the jdk itself, so the call is trivially allowed. This commit adds hidden frames to the stack walk so that the lambda frame created for the method reference is included. Several internal packages are then necessary to filter out of the stack.
This commit is contained in:
parent
a3700ff598
commit
ab690ba23f
4 changed files with 20 additions and 2 deletions
5
docs/changelog/127877.yaml
Normal file
5
docs/changelog/127877.yaml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
pr: 127877
|
||||||
|
summary: Check hidden frames in entitlements
|
||||||
|
area: Infra/Core
|
||||||
|
type: bug
|
||||||
|
issues: []
|
|
@ -10,8 +10,10 @@
|
||||||
package org.elasticsearch.entitlement.bridge;
|
package org.elasticsearch.entitlement.bridge;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE;
|
import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE;
|
||||||
|
import static java.lang.StackWalker.Option.SHOW_HIDDEN_FRAMES;
|
||||||
|
|
||||||
public class Util {
|
public class Util {
|
||||||
/**
|
/**
|
||||||
|
@ -23,6 +25,8 @@ public class Util {
|
||||||
public static final Class<?> NO_CLASS = new Object() {
|
public static final Class<?> NO_CLASS = new Object() {
|
||||||
}.getClass();
|
}.getClass();
|
||||||
|
|
||||||
|
private static final Set<String> skipInternalPackages = Set.of("java.lang.invoke", "java.lang.reflect", "jdk.internal.reflect");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Why would we write this instead of using {@link StackWalker#getCallerClass()}?
|
* Why would we write this instead of using {@link StackWalker#getCallerClass()}?
|
||||||
* Because that method throws {@link IllegalCallerException} if called from the "outermost frame",
|
* Because that method throws {@link IllegalCallerException} if called from the "outermost frame",
|
||||||
|
@ -32,9 +36,10 @@ public class Util {
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused") // Called reflectively from InstrumenterImpl
|
@SuppressWarnings("unused") // Called reflectively from InstrumenterImpl
|
||||||
public static Class<?> getCallerClass() {
|
public static Class<?> getCallerClass() {
|
||||||
Optional<Class<?>> callerClassIfAny = StackWalker.getInstance(RETAIN_CLASS_REFERENCE)
|
Optional<Class<?>> callerClassIfAny = StackWalker.getInstance(Set.of(RETAIN_CLASS_REFERENCE, SHOW_HIDDEN_FRAMES))
|
||||||
.walk(
|
.walk(
|
||||||
frames -> frames.skip(2) // Skip this method and its caller
|
frames -> frames.skip(2) // Skip this method and its caller
|
||||||
|
.filter(frame -> skipInternalPackages.contains(frame.getDeclaringClass().getPackageName()) == false)
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.map(StackWalker.StackFrame::getDeclaringClass)
|
.map(StackWalker.StackFrame::getDeclaringClass)
|
||||||
);
|
);
|
||||||
|
|
|
@ -182,7 +182,9 @@ public record FilesEntitlement(List<FileData> filesData) implements Entitlement
|
||||||
case "config" -> BaseDir.CONFIG;
|
case "config" -> BaseDir.CONFIG;
|
||||||
case "data" -> BaseDir.DATA;
|
case "data" -> BaseDir.DATA;
|
||||||
case "home" -> BaseDir.USER_HOME;
|
case "home" -> BaseDir.USER_HOME;
|
||||||
// NOTE: shared_repo is _not_ accessible to policy files, only internally
|
// it would be nice to limit this to just ES modules, but we don't have a way to plumb that through to here
|
||||||
|
// however, we still don't document in the error case below that shared_repo is valid
|
||||||
|
case "shared_repo" -> BaseDir.SHARED_REPO;
|
||||||
default -> throw new PolicyValidationException(
|
default -> throw new PolicyValidationException(
|
||||||
"invalid relative directory: " + baseDir + ", valid values: [config, data, home]"
|
"invalid relative directory: " + baseDir + ", valid values: [config, data, home]"
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,2 +1,8 @@
|
||||||
|
org.elasticsearch.repository.url:
|
||||||
|
- outbound_network
|
||||||
|
- files:
|
||||||
|
- relative_path: .
|
||||||
|
relative_to: shared_repo
|
||||||
|
mode: read
|
||||||
org.apache.httpcomponents.httpclient:
|
org.apache.httpcomponents.httpclient:
|
||||||
- outbound_network # for URLHttpClient
|
- outbound_network # for URLHttpClient
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue