Skip to content

Commit 642dae4

Browse files
Initial version of the native agent with tagging
1 parent 471f00b commit 642dae4

File tree

10 files changed

+132
-2
lines changed

10 files changed

+132
-2
lines changed

benchmark/benchmarks.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ export UTILS_DIR="${SCRIPT_DIR}/utils"
88
export SHELL_UTILS_DIR="${UTILS_DIR}/shell"
99
export K6_UTILS_DIR="${UTILS_DIR}/k6"
1010
export TRACER="${SCRIPT_DIR}/tracer/dd-java-agent.jar"
11+
NATIVE_LIBRARY=$(readlink --canonicalize "${SCRIPT_DIR}/../native-agent/libdd-java-agent.so")
12+
if [ -f "$NATIVE_LIBRARY" ]; then
13+
export NATIVE_TRACER="-agentpath:$NATIVE_LIBRARY"
14+
else
15+
export NATIVE_TRACER=""
16+
fi
1117
export NO_AGENT_VARIANT="no_agent"
1218

1319
run_benchmarks() {

benchmark/dacapo/benchmark.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@
3535
"JAVA_OPTS": "-javaagent:${TRACER} -Ddd.iast.enabled=true"
3636
}
3737
},
38+
"iast_NATIVE": {
39+
"env": {
40+
"VARIANT": "iast_NATIVE",
41+
"JAVA_OPTS": "${NATIVE_TRACER} -javaagent:${TRACER} -Ddd.iast.enabled=true"
42+
}
43+
},
3844
"iast_GLOBAL": {
3945
"env": {
4046
"VARIANT": "iast_GLOBAL",

benchmark/load/insecure-bank/benchmark.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@
2424
"JAVA_OPTS": "-javaagent:${TRACER} -Ddd.iast.enabled=true"
2525
}
2626
},
27+
"iast_NATIVE": {
28+
"env": {
29+
"VARIANT": "iast_NATIVE",
30+
"JAVA_OPTS": "${NATIVE_TRACER} -javaagent:${TRACER} -Ddd.iast.enabled=true"
31+
}
32+
},
2733
"iast_GLOBAL": {
2834
"env": {
2935
"VARIANT": "iast_GLOBAL",
@@ -36,6 +42,12 @@
3642
"JAVA_OPTS": "-javaagent:${TRACER} -Ddd.iast.enabled=true -Ddd.iast.detection.mode=FULL"
3743
}
3844
},
45+
"iast_NATIVE_FULL": {
46+
"env": {
47+
"VARIANT": "iast_NATIVE_FULL",
48+
"JAVA_OPTS": "${NATIVE_TRACER} -javaagent:${TRACER} -Ddd.iast.enabled=true -Ddd.iast.detection.mode=FULL"
49+
}
50+
},
3951
"iast_INACTIVE": {
4052
"env": {
4153
"VARIANT": "iast_INACTIVE",

benchmark/load/petclinic/benchmark.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@
4141
"VARIANT": "iast",
4242
"JAVA_OPTS": "-javaagent:${TRACER} -Ddd.iast.enabled=true"
4343
}
44+
},
45+
"iast_NATIVE": {
46+
"env": {
47+
"VARIANT": "iast_NATIVE",
48+
"JAVA_OPTS": "${NATIVE_TRACER} -javaagent:${TRACER} -Ddd.iast.enabled=true"
49+
}
4450
}
4551
}
4652
}

dd-smoke-tests/iast-util/src/testFixtures/groovy/datadog/smoketest/AbstractIastServerSmokeTest.groovy

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import org.spockframework.runtime.SpockTimeoutError
1212
import spock.lang.Shared
1313
import spock.util.concurrent.PollingConditions
1414

15+
import java.nio.file.Files
16+
import java.nio.file.Paths
1517
import java.util.concurrent.TimeoutException
1618

1719
@CompileDynamic
@@ -22,6 +24,21 @@ abstract class AbstractIastServerSmokeTest extends AbstractServerSmokeTest {
2224
@Shared
2325
private final JsonSlurper jsonSlurper = new JsonSlurper()
2426

27+
@Override
28+
def javaProperties() {
29+
def source = Paths.get(AbstractIastServerSmokeTest.protectionDomain.codeSource.location.toURI())
30+
while (source != null && !source.endsWith('dd-trace-java')) {
31+
source = source.parent
32+
}
33+
final nativeLib = source.resolve('native-agent').resolve('libdd-java-agent.so')
34+
if (!Files.exists(nativeLib)) {
35+
throw new IllegalArgumentException('Native agent missing')
36+
}
37+
final props = ["-agentpath:$nativeLib".toString()]
38+
super.javaProperties().each { props.add(it) }
39+
return props.toArray(new String[0])
40+
}
41+
2542
@Override
2643
String logLevel() {
2744
return 'debug'

internal-api/build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,9 @@ dependencies {
211211
// it contains annotations that are also present in the instrumented application classes
212212
api "com.datadoghq:dd-javac-plugin-client:0.2.2"
213213

214+
// native agent that should be loaded by the system classloader
215+
api files("$rootDir/native-agent/dd-native-java-agent-0.1.0-SNAPSHOT.jar")
216+
214217
testImplementation project(":utils:test-utils")
215218
testImplementation("org.assertj:assertj-core:3.20.2")
216219
testImplementation libs.bundles.junit5

internal-api/src/main/java/datadog/trace/api/iast/IastContext.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
import datadog.trace.api.gateway.RequestContext;
44
import datadog.trace.api.gateway.RequestContextSlot;
5+
import datadog.trace.api.iast.taint.NativeTaintedObjectsAdapter;
56
import datadog.trace.api.iast.taint.TaintedObjects;
7+
import datadog.trace.api.nagent.iast.NativeTaintedUtils;
68
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
79
import datadog.trace.bootstrap.instrumentation.api.AgentTracer;
810
import java.io.Closeable;
@@ -50,14 +52,27 @@ public static void register(@Nonnull final Provider instance) {
5052
/** Release the current request context, e.g. free resources, add objects to pools, ... */
5153
public abstract void releaseRequestContext(@Nonnull IastContext context);
5254

55+
/**
56+
* Returns the current active tainted objects dictionary reusing the native stub if available
57+
*
58+
* @see #taintedObjectsFn()
59+
*/
60+
@Nullable
61+
public static TaintedObjects taintedObjects() {
62+
if (NativeTaintedUtils.isEnabled()) {
63+
return new NativeTaintedObjectsAdapter(Provider::taintedObjectsFn);
64+
} else {
65+
return taintedObjectsFn();
66+
}
67+
}
68+
5369
/**
5470
* Gets the current active tainted objects dictionary, if no provider is configured this method
5571
* defaults to fetching the dictionary included in the current request context
5672
*
5773
* @see Provider#taintedObjects()
5874
*/
59-
@Nullable
60-
public static TaintedObjects taintedObjects() {
75+
private static TaintedObjects taintedObjectsFn() {
6176
if (INSTANCE == null) {
6277
final IastContext ctx = get();
6378
return ctx == null ? null : ctx.getTaintedObjects();
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package datadog.trace.api.iast.taint;
2+
3+
import datadog.trace.api.nagent.iast.NativeTaintedUtils;
4+
import java.util.Iterator;
5+
import java.util.function.Supplier;
6+
import javax.annotation.Nonnull;
7+
import javax.annotation.Nullable;
8+
9+
public class NativeTaintedObjectsAdapter implements TaintedObjects {
10+
11+
private final Supplier<TaintedObjects> delegateSupplier;
12+
private volatile TaintedObjects delegate;
13+
14+
public NativeTaintedObjectsAdapter(@Nonnull final Supplier<TaintedObjects> delegateSupplier) {
15+
this.delegateSupplier = delegateSupplier;
16+
}
17+
18+
@Nullable
19+
@Override
20+
public TaintedObject taint(@Nonnull final Object obj, @Nonnull final Range[] ranges) {
21+
NativeTaintedUtils.setTainted(obj);
22+
return delegate().taint(obj, ranges);
23+
}
24+
25+
@Nullable
26+
@Override
27+
public TaintedObject get(@Nonnull final Object obj) {
28+
if (isTainted(obj)) {
29+
return delegate().get(obj);
30+
}
31+
return null;
32+
}
33+
34+
@Override
35+
public boolean isTainted(@Nonnull final Object obj) {
36+
return NativeTaintedUtils.isTainted(obj);
37+
}
38+
39+
@Override
40+
public void clear() {
41+
delegate().clear();
42+
}
43+
44+
@Override
45+
public int count() {
46+
return delegate().count();
47+
}
48+
49+
@Nonnull
50+
@Override
51+
public Iterator<TaintedObject> iterator() {
52+
return delegate().iterator();
53+
}
54+
55+
private TaintedObjects delegate() {
56+
if (delegate == null) {
57+
synchronized (this) {
58+
if (delegate == null) {
59+
delegate = delegateSupplier.get();
60+
}
61+
}
62+
}
63+
return delegate;
64+
}
65+
}
1.92 KB
Binary file not shown.

native-agent/libdd-java-agent.so

26.4 KB
Binary file not shown.

0 commit comments

Comments
 (0)