Check hidden frames in entitlements (#127877) (#127947)
Validate Gradle Wrapper / Validation (push) Waiting to run
Details
Validate Gradle Wrapper / Validation (push) Waiting to run
Details
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
671b8d603a
commit
1b919e9689
|
@ -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…
Reference in New Issue