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

View File

@ -58,7 +58,11 @@ public final class AgentInitializer {
} }
private static void execute(PrivilegedExceptionAction<Void> action) throws Exception { 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); doPrivilegedExceptionAction(action);
} else { } else {
action.run(); action.run();

View File

@ -11,6 +11,7 @@ import io.opentelemetry.instrumentation.api.internal.RuntimeVirtualFieldSupplier
import io.opentelemetry.instrumentation.api.util.VirtualField; import io.opentelemetry.instrumentation.api.util.VirtualField;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.security.PrivilegedAction;
final class RuntimeFieldBasedImplementationSupplier final class RuntimeFieldBasedImplementationSupplier
implements RuntimeVirtualFieldSupplier.VirtualFieldSupplier { implements RuntimeVirtualFieldSupplier.VirtualFieldSupplier {
@ -18,6 +19,15 @@ final class RuntimeFieldBasedImplementationSupplier
@Override @Override
public <U extends T, V extends F, T, F> VirtualField<U, V> find( public <U extends T, V extends F, T, F> VirtualField<U, V> find(
Class<T> type, Class<F> fieldType) { 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 { try {
String virtualFieldImplClassName = String virtualFieldImplClassName =
getVirtualFieldImplementationClassName(type.getTypeName(), fieldType.getTypeName()); getVirtualFieldImplementationClassName(type.getTypeName(), fieldType.getTypeName());