Improve security manager support (#11466)
This commit is contained in:
parent
300ad5ebb3
commit
e7d0278fc8
|
@ -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.
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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());
|
||||||
|
|
Loading…
Reference in New Issue