Skip to content

Commit

Permalink
Merge branch 'master' into mario.vidal/increase_string_taint
Browse files Browse the repository at this point in the history
  • Loading branch information
Mariovido authored Sep 23, 2024
2 parents 6d35d2e + 5ca0c5b commit d1f0038
Show file tree
Hide file tree
Showing 39 changed files with 658 additions and 804 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ private enum AgentFeature {
USM(propertyNameToSystemPropertyName(UsmConfig.USM_ENABLED), false),
TELEMETRY(propertyNameToSystemPropertyName(GeneralConfig.TELEMETRY_ENABLED), true),
DEBUGGER(propertyNameToSystemPropertyName(DebuggerConfig.DEBUGGER_ENABLED), false),
EXCEPTION_DEBUGGING(
propertyNameToSystemPropertyName(DebuggerConfig.EXCEPTION_REPLAY_ENABLED), false),
DATA_JOBS(propertyNameToSystemPropertyName(GeneralConfig.DATA_JOBS_ENABLED), false),
AGENTLESS_LOG_SUBMISSION(
propertyNameToSystemPropertyName(GeneralConfig.AGENTLESS_LOG_SUBMISSION_ENABLED), false);
Expand Down Expand Up @@ -149,6 +151,7 @@ public boolean isEnabledByDefault() {
private static boolean usmEnabled = false;
private static boolean telemetryEnabled = true;
private static boolean debuggerEnabled = false;
private static boolean exceptionDebuggingEnabled = false;
private static boolean agentlessLogSubmissionEnabled = false;

/**
Expand Down Expand Up @@ -259,6 +262,7 @@ public static void start(
cwsEnabled = isFeatureEnabled(AgentFeature.CWS);
telemetryEnabled = isFeatureEnabled(AgentFeature.TELEMETRY);
debuggerEnabled = isFeatureEnabled(AgentFeature.DEBUGGER);
exceptionDebuggingEnabled = isFeatureEnabled(AgentFeature.EXCEPTION_DEBUGGING);
agentlessLogSubmissionEnabled = isFeatureEnabled(AgentFeature.AGENTLESS_LOG_SUBMISSION);

if (profilingEnabled) {
Expand Down Expand Up @@ -1069,7 +1073,7 @@ private static void shutdownProfilingAgent(final boolean sync) {
}

private static void maybeStartDebugger(Instrumentation inst, Class<?> scoClass, Object sco) {
if (!debuggerEnabled) {
if (!debuggerEnabled && !exceptionDebuggingEnabled) {
return;
}
if (!remoteConfigEnabled) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ public class CapturedContext implements ValueReferenceResolver {
private String spanId;
private long duration;
private final Map<String, Status> statusByProbeId = new LinkedHashMap<>();
private Map<String, CapturedValue> watches;

public CapturedContext() {}

Expand Down Expand Up @@ -267,6 +268,10 @@ public Map<String, CapturedValue> getStaticFields() {
return staticFields;
}

public Map<String, CapturedValue> getWatches() {
return watches;
}

public Limits getLimits() {
return limits;
}
Expand All @@ -288,6 +293,11 @@ public String getSpanId() {
* instance representation into the corresponding string value.
*/
public void freeze(TimeoutChecker timeoutChecker) {
if (watches != null) {
// freeze only watches
watches.values().forEach(capturedValue -> capturedValue.freeze(timeoutChecker));
return;
}
if (arguments != null) {
arguments.values().forEach(capturedValue -> capturedValue.freeze(timeoutChecker));
}
Expand Down Expand Up @@ -383,6 +393,13 @@ private void putInStaticFields(String name, CapturedValue value) {
staticFields.put(name, value);
}

public void addWatch(CapturedValue value) {
if (watches == null) {
watches = new HashMap<>();
}
watches.put(value.name, value);
}

public static class Status {
public static final Status EMPTY_STATUS = new Status(ProbeImplementation.UNKNOWN);
public static final Status EMPTY_CAPTURING_STATUS =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,37 +26,38 @@ public class WellKnownClasses {

static {
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Class", WellKnownClasses::classToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.String", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Boolean", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Integer", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Long", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Double", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Character", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Byte", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Float", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Short", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.math.BigDecimal", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.math.BigInteger", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.time.Duration", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.time.Instant", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.time.LocalTime", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.time.LocalDate", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.time.LocalDateTime", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.util.UUID", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.net.URI", WellKnownClasses::genericToString);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.String", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Boolean", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Integer", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Long", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Double", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Character", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Byte", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Float", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.lang.Short", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.math.BigDecimal", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.math.BigInteger", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.time.Duration", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.time.Instant", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.time.LocalTime", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.time.LocalDate", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.time.LocalDateTime", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.util.UUID", String::valueOf);
TO_STRING_FINAL_SAFE_CLASSES.put("java.net.URI", String::valueOf);
}

private static final Map<String, Function<Object, String>> SAFE_TO_STRING_FUNCTIONS =
new HashMap<>();

static {
SAFE_TO_STRING_FUNCTIONS.putAll(TO_STRING_FINAL_SAFE_CLASSES);
SAFE_TO_STRING_FUNCTIONS.put(
"java.util.concurrent.atomic.AtomicBoolean", WellKnownClasses::genericToString);
SAFE_TO_STRING_FUNCTIONS.put(
"java.util.concurrent.atomic.AtomicInteger", WellKnownClasses::genericToString);
SAFE_TO_STRING_FUNCTIONS.put(
"java.util.concurrent.atomic.AtomicLong", WellKnownClasses::genericToString);
SAFE_TO_STRING_FUNCTIONS.put("java.util.concurrent.atomic.AtomicBoolean", String::valueOf);
SAFE_TO_STRING_FUNCTIONS.put("java.util.concurrent.atomic.AtomicInteger", String::valueOf);
SAFE_TO_STRING_FUNCTIONS.put("java.util.concurrent.atomic.AtomicLong", String::valueOf);
SAFE_TO_STRING_FUNCTIONS.put("java.io.File", String::valueOf);
// implementations of java.io.file.Path interfaces
SAFE_TO_STRING_FUNCTIONS.put("sun.nio.fs.UnixPath", String::valueOf);
SAFE_TO_STRING_FUNCTIONS.put("sun.nio.fs.WindowsPath", String::valueOf);
}

private static final Set<String> EQUALS_SAFE_CLASSES = new HashSet<>();
Expand All @@ -81,6 +82,9 @@ public class WellKnownClasses {
EQUALS_SAFE_CLASSES.add("java.time.LocalDateTime");
EQUALS_SAFE_CLASSES.add("java.util.UUID");
EQUALS_SAFE_CLASSES.add("java.net.URI");
EQUALS_SAFE_CLASSES.add("java.io.File");
EQUALS_SAFE_CLASSES.add("sun.nio.fs.UnixPath");
EQUALS_SAFE_CLASSES.add("sun.nio.fs.WindowsPath");
}

private static final Set<String> STRING_PRIMITIVES =
Expand All @@ -93,7 +97,10 @@ public class WellKnownClasses {
"java.time.LocalTime",
"java.time.LocalDate",
"java.time.LocalDateTime",
"java.util.UUID"));
"java.util.UUID",
"java.io.File",
"sun.nio.fs.UnixPath",
"sun.nio.fs.WindowsPath"));

private static final Map<Class<?>, Map<String, Function<Object, CapturedContext.CapturedValue>>>
SPECIAL_TYPE_ACCESS = new HashMap<>();
Expand Down Expand Up @@ -236,10 +243,6 @@ private static String classToString(Object o) {
return ((Class<?>) o).getTypeName();
}

private static String genericToString(Object o) {
return String.valueOf(o);
}

public static boolean isEqualsSafe(Class<?> clazz) {
return clazz.isPrimitive()
|| clazz.isEnum()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,11 +58,6 @@ public class DebuggerAgent {
public static synchronized void run(
Instrumentation instrumentation, SharedCommunicationObjects sco) {
Config config = Config.get();
if (!config.isDebuggerEnabled()) {
LOGGER.info("Debugger agent disabled");
return;
}
LOGGER.info("Starting Dynamic Instrumentation");
ClassesToRetransformFinder classesToRetransformFinder = new ClassesToRetransformFinder();
setupSourceFileTracking(instrumentation, classesToRetransformFinder);
Redaction.addUserDefinedKeywords(config);
Expand Down Expand Up @@ -95,6 +90,7 @@ public static synchronized void run(
DebuggerContext.initTracer(new DebuggerTracer(debuggerSink.getProbeStatusSink()));
DefaultExceptionDebugger defaultExceptionDebugger = null;
if (config.isDebuggerExceptionEnabled()) {
LOGGER.info("Starting Exception Replay");
defaultExceptionDebugger =
new DefaultExceptionDebugger(
configurationUpdater,
Expand All @@ -112,6 +108,36 @@ public static synchronized void run(
setupInstrumentTheWorldTransformer(
config, instrumentation, debuggerSink, statsdMetricForwarder);
}
// Dynamic Instrumentation
if (config.isDebuggerEnabled()) {
startDynamicInstrumentation(
instrumentation, sco, config, configurationUpdater, debuggerSink, classNameFiltering);
}
try {
/*
Note: shutdown hooks are tricky because JVM holds reference for them forever preventing
GC for anything that is reachable from it.
*/
Runtime.getRuntime().addShutdownHook(new ShutdownHook(configurationPoller, debuggerSink));
} catch (final IllegalStateException ex) {
// The JVM is already shutting down.
}
ExceptionProbeManager exceptionProbeManager =
defaultExceptionDebugger != null
? defaultExceptionDebugger.getExceptionProbeManager()
: null;
TracerFlare.addReporter(
new DebuggerReporter(configurationUpdater, sink, exceptionProbeManager));
}

private static void startDynamicInstrumentation(
Instrumentation instrumentation,
SharedCommunicationObjects sco,
Config config,
ConfigurationUpdater configurationUpdater,
DebuggerSink debuggerSink,
ClassNameFiltering classNameFiltering) {
LOGGER.info("Starting Dynamic Instrumentation");
String probeFileLocation = config.getDebuggerProbeFileLocation();
if (probeFileLocation != null) {
Path probeFilePath = Paths.get(probeFileLocation);
Expand All @@ -133,24 +159,9 @@ public static synchronized void run(
}
}
subscribeConfigurationPoller(config, configurationUpdater, symDBEnablement);
try {
/*
Note: shutdown hooks are tricky because JVM holds reference for them forever preventing
GC for anything that is reachable from it.
*/
Runtime.getRuntime().addShutdownHook(new ShutdownHook(configurationPoller, debuggerSink));
} catch (final IllegalStateException ex) {
// The JVM is already shutting down.
}
} else {
LOGGER.debug("No configuration poller available from SharedCommunicationObjects");
}
ExceptionProbeManager exceptionProbeManager =
defaultExceptionDebugger != null
? defaultExceptionDebugger.getExceptionProbeManager()
: null;
TracerFlare.addReporter(
new DebuggerReporter(configurationUpdater, sink, exceptionProbeManager));
}

private static DebuggerSink createDebuggerSink(Config config, ProbeStatusSink probeStatusSink) {
Expand Down
Loading

0 comments on commit d1f0038

Please sign in to comment.