Improve security manager support (#11466)

This commit is contained in:
Lauri Tulmin 2024-05-29 09:11:22 +03:00 committed by GitHub
parent 300ad5ebb3
commit e7d0278fc8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 31 additions and 7 deletions

View File

@ -6,6 +6,7 @@
package io.opentelemetry.instrumentation.api.internal;
import io.opentelemetry.api.trace.SpanKind;
import java.security.PrivilegedAction;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
@ -88,12 +89,14 @@ public final class SupportabilityMetrics {
ScheduledExecutorService executor =
Executors.newScheduledThreadPool(
1,
runnable -> {
Thread result = new Thread(runnable, "supportability_metrics_reporter");
result.setDaemon(true);
result.setContextClassLoader(null);
return result;
});
runnable ->
doPrivileged(
() -> {
Thread result = new Thread(runnable, "supportability_metrics_reporter");
result.setDaemon(true);
result.setContextClassLoader(null);
return result;
}));
executor.scheduleAtFixedRate(this::report, 5, 5, TimeUnit.SECONDS);
// the condition below will always be false, but by referencing the executor it ensures the
// executor can't become unreachable in the middle of the scheduleAtFixedRate() method
@ -107,6 +110,13 @@ public final class SupportabilityMetrics {
return this;
}
private static <T> T doPrivileged(PrivilegedAction<T> action) {
if (System.getSecurityManager() == null) {
return action.run();
}
return java.security.AccessController.doPrivileged(action);
}
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.

View File

@ -58,7 +58,11 @@ public final class AgentInitializer {
}
private static void execute(PrivilegedExceptionAction<Void> action) throws Exception {
if (isSecurityManagerSupportEnabled && System.getSecurityManager() != null) {
// When security manager support is enabled we use doPrivileged even if security manager is not
// present because security manager could be installed later. ByteBuddy initialization captures
// the access control context used during transformation. If we don't use doPrivileged here then
// that context will not have the privileges if security manager is installed later.
if (isSecurityManagerSupportEnabled) {
doPrivilegedExceptionAction(action);
} else {
action.run();

View File

@ -11,6 +11,7 @@ import io.opentelemetry.instrumentation.api.internal.RuntimeVirtualFieldSupplier
import io.opentelemetry.instrumentation.api.util.VirtualField;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.security.PrivilegedAction;
final class RuntimeFieldBasedImplementationSupplier
implements RuntimeVirtualFieldSupplier.VirtualFieldSupplier {
@ -18,6 +19,15 @@ final class RuntimeFieldBasedImplementationSupplier
@Override
public <U extends T, V extends F, T, F> VirtualField<U, V> find(
Class<T> type, Class<F> fieldType) {
if (System.getSecurityManager() == null) {
return findInternal(type, fieldType);
}
return java.security.AccessController.doPrivileged(
(PrivilegedAction<VirtualField<U, V>>) () -> findInternal(type, fieldType));
}
private static <U extends T, V extends F, T, F> VirtualField<U, V> findInternal(
Class<T> type, Class<F> fieldType) {
try {
String virtualFieldImplClassName =
getVirtualFieldImplementationClassName(type.getTypeName(), fieldType.getTypeName());