aboutsummaryrefslogtreecommitdiff
path: root/agent
diff options
context:
space:
mode:
authorFabian Meumertzheim <meumertzheim@code-intelligence.com>2021-10-21 12:06:58 +0200
committerFabian Meumertzheim <fabian@meumertzhe.im>2021-10-21 14:09:41 +0200
commitd4a1ce3f2e227bc30bcd2d97b623c193197e293e (patch)
tree7bb451018e0b080c8306921598430063d1dcf014 /agent
parent4d925f2464b4ccf759bd4d957d5db9aa749e85b3 (diff)
downloadjazzer-api-d4a1ce3f2e227bc30bcd2d97b623c193197e293e.tar.gz
Add Jazzer.consume to the Jazzer API
This requires moving AutofuzzConstructionException to api package.
Diffstat (limited to 'agent')
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/api/AutofuzzConstructionException.java (renamed from agent/src/main/java/com/code_intelligence/jazzer/autofuzz/AutofuzzConstructionException.java)7
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/api/Jazzer.java38
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/autofuzz/FuzzTarget.java1
-rw-r--r--agent/src/main/java/com/code_intelligence/jazzer/autofuzz/Meta.java1
-rw-r--r--agent/src/test/java/com/code_intelligence/jazzer/api/AutofuzzTest.java45
-rw-r--r--agent/src/test/java/com/code_intelligence/jazzer/api/BUILD.bazel21
6 files changed, 110 insertions, 3 deletions
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/AutofuzzConstructionException.java b/agent/src/main/java/com/code_intelligence/jazzer/api/AutofuzzConstructionException.java
index 7cb41d4b..93340ee8 100644
--- a/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/AutofuzzConstructionException.java
+++ b/agent/src/main/java/com/code_intelligence/jazzer/api/AutofuzzConstructionException.java
@@ -12,11 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.code_intelligence.jazzer.autofuzz;
+package com.code_intelligence.jazzer.api;
+// An exception wrapping a Throwable thrown during the construction of parameters for, but not the
+// actual invocation of an autofuzzed method.
/**
- * An exception wrapping a {@link Throwable} thrown during the construction of parameters for, but
- * not the actual invocation of an autofuzzed method.
+ * Only used internally.
*/
public class AutofuzzConstructionException extends RuntimeException {
public AutofuzzConstructionException() {
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/api/Jazzer.java b/agent/src/main/java/com/code_intelligence/jazzer/api/Jazzer.java
index a4f6f740..930d8f0f 100644
--- a/agent/src/main/java/com/code_intelligence/jazzer/api/Jazzer.java
+++ b/agent/src/main/java/com/code_intelligence/jazzer/api/Jazzer.java
@@ -29,6 +29,8 @@ final public class Jazzer {
private static MethodHandle traceStrstr = null;
private static MethodHandle traceMemcmp = null;
+ private static MethodHandle consume = null;
+
static {
try {
jazzerInternal = Class.forName("com.code_intelligence.jazzer.runtime.JazzerInternal");
@@ -48,6 +50,11 @@ final public class Jazzer {
MethodType.methodType(void.class, byte[].class, byte[].class, int.class, int.class);
traceMemcmp = MethodHandles.publicLookup().findStatic(
traceDataFlowNativeCallbacks, "traceMemcmp", traceMemcmpType);
+
+ Class<?> metaClass = Class.forName("com.code_intelligence.jazzer.autofuzz.Meta");
+ MethodType consumeType =
+ MethodType.methodType(Object.class, FuzzedDataProvider.class, Class.class);
+ consume = MethodHandles.publicLookup().findStatic(metaClass, "consume", consumeType);
} catch (ClassNotFoundException ignore) {
// Not running in the context of the agent. This is fine as long as no methods are called on
// this class.
@@ -63,6 +70,31 @@ final public class Jazzer {
private Jazzer() {}
/**
+ * Attempts to construct an instance of {@code type} from the fuzzer input using only public
+ * methods available on the classpath.
+ *
+ * <b>Note:</b> This function is inherently heuristic and may fail to return meaningful values for
+ * a variety of reasons.
+ *
+ * @param data the {@link FuzzedDataProvider} instance provided to {@code fuzzerTestOneInput}.
+ * @param type the {@link Class} to construct an instance of.
+ * @return an instance of {@code type} constructed from the fuzzer input, or {@code null} if
+ * autofuzz failed to create an instance.
+ */
+ @SuppressWarnings("unchecked")
+ public static <T> T consume(FuzzedDataProvider data, Class<T> type) {
+ try {
+ return (T) consume.invokeExact(data, type);
+ } catch (AutofuzzConstructionException ignored) {
+ return null;
+ } catch (Throwable t) {
+ rethrowUnchecked(t);
+ // Not reached.
+ return null;
+ }
+ }
+
+ /**
* Instructs the fuzzer to guide its mutations towards making {@code current} equal to {@code
* target}.
*
@@ -148,4 +180,10 @@ final public class Jazzer {
}
}
}
+
+ // Rethrows a (possibly checked) exception while avoiding a throws declaration.
+ @SuppressWarnings("unchecked")
+ private static <T extends Throwable> void rethrowUnchecked(Throwable t) throws T {
+ throw(T) t;
+ }
}
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/FuzzTarget.java b/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/FuzzTarget.java
index ea1b9a96..ce7df069 100644
--- a/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/FuzzTarget.java
+++ b/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/FuzzTarget.java
@@ -14,6 +14,7 @@
package com.code_intelligence.jazzer.autofuzz;
+import com.code_intelligence.jazzer.api.AutofuzzConstructionException;
import com.code_intelligence.jazzer.api.FuzzedDataProvider;
import com.code_intelligence.jazzer.utils.SimpleGlobMatcher;
import com.code_intelligence.jazzer.utils.Utils;
diff --git a/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/Meta.java b/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/Meta.java
index ad439730..4a679b8f 100644
--- a/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/Meta.java
+++ b/agent/src/main/java/com/code_intelligence/jazzer/autofuzz/Meta.java
@@ -14,6 +14,7 @@
package com.code_intelligence.jazzer.autofuzz;
+import com.code_intelligence.jazzer.api.AutofuzzConstructionException;
import com.code_intelligence.jazzer.api.FuzzedDataProvider;
import com.code_intelligence.jazzer.utils.Utils;
import io.github.classgraph.ClassGraph;
diff --git a/agent/src/test/java/com/code_intelligence/jazzer/api/AutofuzzTest.java b/agent/src/test/java/com/code_intelligence/jazzer/api/AutofuzzTest.java
new file mode 100644
index 00000000..b4696ce8
--- /dev/null
+++ b/agent/src/test/java/com/code_intelligence/jazzer/api/AutofuzzTest.java
@@ -0,0 +1,45 @@
+// Copyright 2021 Code Intelligence GmbH
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.code_intelligence.jazzer.api;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+
+import java.util.Arrays;
+import java.util.Collections;
+import org.junit.Test;
+
+public class AutofuzzTest {
+ public interface UnimplementedInterface {}
+
+ public interface ImplementedInterface {}
+ public static class ImplementingClass implements ImplementedInterface {}
+
+ @Test
+ public void testConsume() {
+ FuzzedDataProvider data = CannedFuzzedDataProvider.create(
+ Arrays.asList((byte) 1 /* do not return null */, 0 /* first class on the classpath */,
+ (byte) 1 /* do not return null */, 0 /* first constructor */));
+ ImplementedInterface result = Jazzer.consume(data, ImplementedInterface.class);
+ assertNotNull(result);
+ }
+
+ @Test
+ public void testConsumeFailsWithoutException() {
+ FuzzedDataProvider data = CannedFuzzedDataProvider.create(Collections.singletonList(
+ (byte) 1 /* do not return null without searching for implementing classes */));
+ assertNull(Jazzer.consume(data, UnimplementedInterface.class));
+ }
+}
diff --git a/agent/src/test/java/com/code_intelligence/jazzer/api/BUILD.bazel b/agent/src/test/java/com/code_intelligence/jazzer/api/BUILD.bazel
new file mode 100644
index 00000000..9192ff77
--- /dev/null
+++ b/agent/src/test/java/com/code_intelligence/jazzer/api/BUILD.bazel
@@ -0,0 +1,21 @@
+java_test(
+ name = "AutofuzzTest",
+ size = "small",
+ srcs = [
+ "AutofuzzTest.java",
+ ],
+ env = {
+ # Also consider implementing classes from com.code_intelligence.jazzer.*.
+ "JAZZER_AUTOFUZZ_TESTING": "1",
+ },
+ test_class = "com.code_intelligence.jazzer.api.AutofuzzTest",
+ runtime_deps = [
+ "//agent/src/main/java/com/code_intelligence/jazzer/autofuzz",
+ # Needed for JazzerInternal.
+ "//agent/src/main/java/com/code_intelligence/jazzer/runtime",
+ ],
+ deps = [
+ "//agent/src/main/java/com/code_intelligence/jazzer/api",
+ "@maven//:junit_junit",
+ ],
+)