Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,8 @@ void onConstantPool(
@Nonnull TypeDescription type, @Nonnull ConstantPool pool, final byte[] classFile);
}

private interface TypedAdvice {
// Kept public only for testing
public interface TypedAdvice {
byte getType();

static CallSiteAdvice withType(final CallSiteAdvice advice, final byte type) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -360,10 +360,12 @@ public void visitMethodInsn(
@Override
public void advice(final String owner, final String name, final String descriptor) {
if (isSuperCall) {
// append this to the stack after super call
mv.visitIntInsn(Opcodes.ALOAD, 0);
mv.visitIntInsn(Opcodes.ALOAD, 0); // append this to the stack after super call
mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, descriptor, false);
mv.visitInsn(Opcodes.POP); // pop the result of the advice call
} else {
mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, descriptor, false);
}
mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, descriptor, false);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class BaseCallSiteTest extends DDSpecification {
advices
.computeIfAbsent(owner, t -> [:])
.computeIfAbsent(method, m -> [:])
.put(descriptor, advice)
.put(descriptor, Advices.TypedAdvice.withType(advice, type))
}
addHelpers(_ as String[]) >> {
Collections.addAll(helpers, it[0] as String[])
Expand Down Expand Up @@ -83,6 +83,9 @@ class BaseCallSiteTest extends DDSpecification {
getHelpers() >> {
helpers as String[]
}
typeOf(_ as CallSiteAdvice) >> {
((Advices.TypedAdvice) it[0]).type
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class CallSiteInstrumentationTest extends BaseCallSiteTest {
0 * builder.visit(_ as AsmVisitorWrapper) >> builder
}

void 'test call site transformer with super call in ctor'() {
void 'test call site transformer with super call in ctor (#test)'() {
setup:
SuperInCtorExampleAdvice.CALLS.set(0)
final source = Type.getType(SuperInCtorExample)
Expand All @@ -91,11 +91,16 @@ class CallSiteInstrumentationTest extends BaseCallSiteTest {
when:
final transformedClass = transformType(source, target, callSiteTransformer)
final transformed = loadClass(target, transformedClass)
final reader = transformed.newInstance("test")
final reader = transformed.newInstance(param)

then:
reader != null
SuperInCtorExampleAdvice.CALLS.get() > 0

where:
param | test
"test" | "Operand stack underflow"
new StringBuilder("test") | "Inconsistent stackmap frames"
}

static class StringCallSites implements CallSites, TestCallSites {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,15 @@
public class SuperInCtorExample extends StringReader {

public SuperInCtorExample(String s) {
// triggers APPSEC-55918
super(s + new StringReader(s + "Test" + new StringBuilder("another test")));
}

public SuperInCtorExample(StringBuilder s) {
super(s.toString());
// triggers APPSEC-58131
if (s.length() == 0) {
throw new IllegalArgumentException();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package datadog.trace.instrumentation.java.io

import datadog.trace.api.iast.InstrumentationBridge
import datadog.trace.api.iast.propagation.PropagationModule
import foo.bar.TestCustomInputStreamReader
import foo.bar.TestInputStreamReaderSuite

import java.nio.charset.Charset
Expand All @@ -27,4 +28,21 @@ class InputStreamReaderCallSiteTest extends BaseIoCallSiteTest{
[new ByteArrayInputStream("test".getBytes())]// Reader input
]
}

void 'test InputStreamReader.<init> with super call and parameter'(){
// XXX: Do not modify the constructor call here. Regression test for APPSEC-58131.
given:
PropagationModule iastModule = Mock(PropagationModule)
InstrumentationBridge.registerIastModule(iastModule)

when:
new TestCustomInputStreamReader(*args)

then:
1 * iastModule.taintObjectIfTainted(_ as InputStreamReader, _ as InputStream)
0 * _

where:
args << [[new ByteArrayInputStream("test".getBytes()), Charset.defaultCharset()],]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package foo.bar;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.Charset;

public class TestCustomInputStreamReader extends InputStreamReader {

public TestCustomInputStreamReader(final InputStream in) throws IOException {
super(in);
}

public TestCustomInputStreamReader(final InputStream in, final Charset charset)
throws IOException {
// XXX: DO NOT MODIFY THIS CODE. This is testing a very specific error (APPSEC-58131).
// This caused the following error:
// VerifyError: Inconsistent stackmap frames at branch target \d
// Reason: urrent frame's stack size doesn't match stackmap.
// To trigger this, it is necessary to consume an argument after the super call.
super(in, charset);
if (charset != null) {
System.out.println("Using charset: " + charset.name());
}
}
}
Loading