From eb98d0407a40c3ef9075f49d03f9d52e374ff93d Mon Sep 17 00:00:00 2001 From: Stuart McCulloch Date: Fri, 5 Dec 2025 11:24:45 +0000 Subject: [PATCH] Disable process advice until after agent tracer is registered This avoids a potential reentrant situation when tracer debug is enabled: 1. The full `Config` is logged during startup in its constructor 2. This includes any lazy config fields, such as the `hostname` 3. If the host is not available in the environment/host-files then `Config` calls the `hostname` command using `Runtime.exec(...)` 4. The `Runtime.exec(...)` call is intercepted by the process advice 5. The process advice calls `Config.get()` to see if RASP is enabled 6. `Config.get()` returns `null` as the config is still being built The resulting NPE is caught before it escapes to the application, but it still results in log-spam that could confuse investigations. --- .../java/lang/ProcessImplStartAdvice.java | 10 ++++------ .../java/lang/RuntimeExecStringAdvice.java | 15 +++++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/dd-java-agent/instrumentation/java/java-lang/java-lang-1.8/src/main/java/datadog/trace/instrumentation/java/lang/ProcessImplStartAdvice.java b/dd-java-agent/instrumentation/java/java-lang/java-lang-1.8/src/main/java/datadog/trace/instrumentation/java/lang/ProcessImplStartAdvice.java index 70feb96924d..71f5bde8cdc 100644 --- a/dd-java-agent/instrumentation/java/java-lang/java-lang-1.8/src/main/java/datadog/trace/instrumentation/java/lang/ProcessImplStartAdvice.java +++ b/dd-java-agent/instrumentation/java/java-lang/java-lang-1.8/src/main/java/datadog/trace/instrumentation/java/lang/ProcessImplStartAdvice.java @@ -3,22 +3,20 @@ import datadog.trace.bootstrap.instrumentation.api.AgentSpan; import datadog.trace.bootstrap.instrumentation.api.AgentTracer; import datadog.trace.bootstrap.instrumentation.api.java.lang.ProcessImplInstrumentationHelpers; -import java.io.IOException; import net.bytebuddy.asm.Advice; class ProcessImplStartAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static AgentSpan startSpan(@Advice.Argument(0) final String[] command) throws IOException { + public static AgentSpan beforeStart(@Advice.Argument(0) final String[] command) { if (!ProcessImplInstrumentationHelpers.ONLINE) { return null; } - if (command.length == 0) { + if (command.length == 0 || !AgentTracer.isRegistered()) { return null; } - final AgentTracer.TracerAPI tracer = AgentTracer.get(); - final AgentSpan span = tracer.startSpan("appsec", "command_execution"); + final AgentSpan span = AgentTracer.startSpan("appsec", "command_execution"); span.setSpanType("system"); span.setResourceName(ProcessImplInstrumentationHelpers.determineResource(command)); span.setTag("component", "subprocess"); @@ -29,7 +27,7 @@ public static AgentSpan startSpan(@Advice.Argument(0) final String[] command) th } @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) - public static void endSpan( + public static void afterStart( @Advice.Return Process p, @Advice.Enter AgentSpan span, @Advice.Thrown Throwable t) { if (span == null) { return; diff --git a/dd-java-agent/instrumentation/java/java-lang/java-lang-1.8/src/main/java/datadog/trace/instrumentation/java/lang/RuntimeExecStringAdvice.java b/dd-java-agent/instrumentation/java/java-lang/java-lang-1.8/src/main/java/datadog/trace/instrumentation/java/lang/RuntimeExecStringAdvice.java index c8b24590609..574b9f829ed 100644 --- a/dd-java-agent/instrumentation/java/java-lang/java-lang-1.8/src/main/java/datadog/trace/instrumentation/java/lang/RuntimeExecStringAdvice.java +++ b/dd-java-agent/instrumentation/java/java-lang/java-lang-1.8/src/main/java/datadog/trace/instrumentation/java/lang/RuntimeExecStringAdvice.java @@ -1,20 +1,23 @@ package datadog.trace.instrumentation.java.lang; +import datadog.trace.bootstrap.instrumentation.api.AgentTracer; import datadog.trace.bootstrap.instrumentation.api.java.lang.ProcessImplInstrumentationHelpers; -import java.io.IOException; import net.bytebuddy.asm.Advice; class RuntimeExecStringAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void beforeExec(@Advice.Argument(0) final String command) throws IOException { - if (command == null) { - return; + public static boolean beforeExec(@Advice.Argument(0) final String command) { + if (command == null || !AgentTracer.isRegistered()) { + return false; } ProcessImplInstrumentationHelpers.shiRaspCheck(command); + return true; } @Advice.OnMethodExit(suppress = Throwable.class, onThrowable = Throwable.class) - public static void afterExec() { - ProcessImplInstrumentationHelpers.resetCheckShi(); + public static void afterExec(@Advice.Enter boolean checking) { + if (checking) { + ProcessImplInstrumentationHelpers.resetCheckShi(); + } } }