diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SupportabilityMetrics.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SupportabilityMetrics.java index 146dcf7f83..cf91c4274c 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SupportabilityMetrics.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SupportabilityMetrics.java @@ -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 doPrivileged(PrivilegedAction 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. diff --git a/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java b/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java index c809ed9b60..5410c883c7 100644 --- a/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java +++ b/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java @@ -58,7 +58,11 @@ public final class AgentInitializer { } private static void execute(PrivilegedExceptionAction 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(); diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/field/RuntimeFieldBasedImplementationSupplier.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/field/RuntimeFieldBasedImplementationSupplier.java index b2f8a21f45..47cc9e4f15 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/field/RuntimeFieldBasedImplementationSupplier.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/field/RuntimeFieldBasedImplementationSupplier.java @@ -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 VirtualField find( Class type, Class fieldType) { + if (System.getSecurityManager() == null) { + return findInternal(type, fieldType); + } + return java.security.AccessController.doPrivileged( + (PrivilegedAction>) () -> findInternal(type, fieldType)); + } + + private static VirtualField findInternal( + Class type, Class fieldType) { try { String virtualFieldImplClassName = getVirtualFieldImplementationClassName(type.getTypeName(), fieldType.getTypeName());