diff --git a/.github/workflows/fuzzing-featured.yaml b/.github/workflows/fuzzing-featured.yaml index bdf608c2b..a5680d5b9 100644 --- a/.github/workflows/fuzzing-featured.yaml +++ b/.github/workflows/fuzzing-featured.yaml @@ -57,7 +57,7 @@ jobs: shell: bash - id: build-jazzer name: Build Jazzer deps - run: cd $CHECKOUT_DIR && bazel build //deploy:jazzer-junit-project //deploy:jazzer-project //deploy:jazzer-api-project //selffuzz:jazzer_selffuzz + run: cd $CHECKOUT_DIR && bazel build //deploy:jazzer-junit-project //deploy:jazzer-project //deploy:jazzer-api-project //selffuzz:jazzer_selffuzz //selffuzz:jazzer_api_selffuzz - id: build-fuzzers name: Build Fuzzers diff --git a/.github/workflows/fuzzing.yaml b/.github/workflows/fuzzing.yaml index 45d42dd69..13a8ef5c4 100644 --- a/.github/workflows/fuzzing.yaml +++ b/.github/workflows/fuzzing.yaml @@ -49,7 +49,7 @@ jobs: shell: bash - id: build-jazzer name: Build Jazzer deps - run: cd $CHECKOUT_DIR && bazel build //deploy:jazzer-junit-project //deploy:jazzer-project //deploy:jazzer-api-project //selffuzz:jazzer_selffuzz + run: cd $CHECKOUT_DIR && bazel build //deploy:jazzer-junit-project //deploy:jazzer-project //deploy:jazzer-api-project //selffuzz:jazzer_selffuzz //selffuzz:jazzer_api_selffuzz - id: build-fuzzers name: Build Fuzzers diff --git a/selffuzz/BUILD.bazel b/selffuzz/BUILD.bazel index c6298e6fe..44ea77ec8 100644 --- a/selffuzz/BUILD.bazel +++ b/selffuzz/BUILD.bazel @@ -6,3 +6,10 @@ jar_jar( rules = "selffuzz_shade_rules.jarjar", visibility = ["__subpackages__"], ) + +jar_jar( + name = "jazzer_api_selffuzz", + input_jar = "//src/main/java/com/code_intelligence/jazzer/api:api", + rules = "selffuzz_shade_rules.jarjar", + visibility = ["__subpackages__"], +) diff --git a/selffuzz/pom.xml b/selffuzz/pom.xml index 82cc5511f..39026a16e 100644 --- a/selffuzz/pom.xml +++ b/selffuzz/pom.xml @@ -121,6 +121,13 @@ system ${project.basedir}/../bazel-bin/selffuzz/jazzer_selffuzz.jar + + com.code-intelligence.selffuzz + jazzer-api + dev + system + ${project.basedir}/../bazel-bin/selffuzz/jazzer_api_selffuzz.jar + com.google.truth truth diff --git a/selffuzz/selffuzz_shade_rules.jarjar b/selffuzz/selffuzz_shade_rules.jarjar index 8e508db58..61aab6968 100644 --- a/selffuzz/selffuzz_shade_rules.jarjar +++ b/selffuzz/selffuzz_shade_rules.jarjar @@ -1 +1,5 @@ +# this is loaded in a special way at runtime and so we can't shade it but it should be safe to share between selffuzz +# and normal jazzer. In order to not shade it, we make a rule to transform it to itself and then have the +# general rule because a file will be transformed by the first rule where it fits the filter +rule com.code_intelligence.jazzer.utils.UnsafeProvider com.code_intelligence.jazzer.utils.UnsafeProvider rule com.code_intelligence.jazzer.** com.code_intelligence.selffuzz.jazzer.@1 diff --git a/selffuzz/src/test/java/com/code_intelligence/selffuzz/driver/BUILD.bazel b/selffuzz/src/test/java/com/code_intelligence/selffuzz/driver/BUILD.bazel new file mode 100644 index 000000000..69908255f --- /dev/null +++ b/selffuzz/src/test/java/com/code_intelligence/selffuzz/driver/BUILD.bazel @@ -0,0 +1,27 @@ +load("//bazel:fuzz_target.bzl", "java_fuzz_target_test") + +# Mutator fuzz tests define a low `runs` to only start and iterate +# a few times via Bazel. Long running fuzzing is executed in CI Sense through +# the CI pipeline integration. + +java_fuzz_target_test( + name = "FuzzedDataProviderImplFuzzTest", + srcs = ["FuzzedDataProviderImplFuzzTest.java"], + fuzzer_args = [ + "--experimental_mutator", + "-runs=1000", + ], + target_class = "com.code_intelligence.selffuzz.driver.FuzzedDataProviderImplFuzzTest", + verify_crash_reproducer = False, + deps = [ + "//selffuzz:jazzer_api_selffuzz", + "//selffuzz:jazzer_selffuzz", + "//src/main/java/com/code_intelligence/jazzer/driver:fuzzed_data_provider_impl", + "//src/main/java/com/code_intelligence/jazzer/junit:fuzz_test", + "//src/main/java/com/code_intelligence/jazzer/mutation/annotation", + "//src/main/native/com/code_intelligence/jazzer/driver:jazzer_fuzzed_data_provider", + "@maven//:org_junit_jupiter_junit_jupiter_api", + "@maven//:org_junit_jupiter_junit_jupiter_engine", + "@maven//:org_junit_platform_junit_platform_launcher", + ], +) diff --git a/selffuzz/src/test/java/com/code_intelligence/selffuzz/driver/FuzzedDataProviderImplFuzzTest.java b/selffuzz/src/test/java/com/code_intelligence/selffuzz/driver/FuzzedDataProviderImplFuzzTest.java new file mode 100644 index 000000000..a320bd0b1 --- /dev/null +++ b/selffuzz/src/test/java/com/code_intelligence/selffuzz/driver/FuzzedDataProviderImplFuzzTest.java @@ -0,0 +1,471 @@ +/* + * Copyright 2023 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.selffuzz.driver; + +import com.code_intelligence.jazzer.junit.FuzzTest; +import com.code_intelligence.jazzer.mutation.annotation.NotNull; +import com.code_intelligence.selffuzz.jazzer.api.FuzzedDataProvider; +import com.code_intelligence.selffuzz.jazzer.driver.FuzzedDataProviderImpl; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.function.Consumer; + +public class FuzzedDataProviderImplFuzzTest { + @FuzzTest + void fuzzedDataProviderTest(byte @NotNull[] buf) { + try (FuzzedDataProviderImpl data = FuzzedDataProviderImpl.withJavaData(buf)) { + List> actionList = getActionList(); + + while (data.remainingBytes() > 0) { + Consumer action = data.pickValue(actionList); + action.accept(data); + } + } + } + + List> getActionList() { + return Collections.unmodifiableList(Arrays.asList( + // clang-format off + // clang-format would compress this into multiple functions per line which I think looks worse + this::testBoolean, + this::testBooleans, + this::testByte, + this::testByteMinMax, + this::testBytes, + this::testRemainingAsBytes, + this::testShort, + this::testShortMinMax, + this::testShorts, + this::testInt, + this::testIntMinMax, + this::testInts, + this::testLong, + this::testLongMinMax, + this::testLongs, + this::testFloat, + this::testRegularFloat, + this::testRegularFloatMinMax, + this::testProbabilityFloat, + this::testDouble, + this::testRegularDouble, + this::testRegularDoubleMinMax, + this::testProbabilityDouble, + this::testChar, + this::testConsumeCharMinMax, + this::testCharNoSurrogates, + this::testString, + this::testRemainingAsString, + this::testAsciiString, + this::testRemainingAsAsciiString, + this::testPickValueCollection, + this::testPickValueArray, + this::testPickValueBoolean, + this::testPickValueByte, + this::testPickValueShort, + this::testPickValueInt, + this::testPickValueLong, + this::testPickValueDouble, + this::testPickValueFloat, + this::testPickValueChar, + this::testPickValuesCollection, + this::testPickValuesArray + // clang-format on + )); + } + + void testBoolean(FuzzedDataProvider data) { + data.consumeBoolean(); + } + + void testBooleans(FuzzedDataProvider data) { + int length = data.consumeInt(); + if (length < 0) { + return; + } + data.consumeBooleans(length); + } + + void testByte(FuzzedDataProvider data) { + data.consumeByte(); + } + + void testByteMinMax(FuzzedDataProvider data) { + byte min = data.consumeByte(); + byte max = data.consumeByte(); + if (min > max) { + return; + } + data.consumeByte(min, max); + } + + void testBytes(FuzzedDataProvider data) { + int length = data.consumeInt(); + if (length < 0) { + return; + } + data.consumeBytes(length); + } + + void testRemainingAsBytes(FuzzedDataProvider data) { + data.consumeRemainingAsBytes(); + } + + void testShort(FuzzedDataProvider data) { + data.consumeShort(); + } + + void testShortMinMax(FuzzedDataProvider data) { + short min = data.consumeShort(); + short max = data.consumeShort(); + if (min > max) { + return; + } + data.consumeShort(min, max); + } + + void testShorts(FuzzedDataProvider data) { + int length = data.consumeInt(); + if (length < 0) { + return; + } + data.consumeShorts(length); + } + + void testInt(FuzzedDataProvider data) { + data.consumeInt(); + } + + void testIntMinMax(FuzzedDataProvider data) { + int min = data.consumeInt(); + int max = data.consumeInt(); + if (min > max) { + return; + } + data.consumeInt(min, max); + } + + void testInts(FuzzedDataProvider data) { + int length = data.consumeInt(); + if (length < 0) { + return; + } + data.consumeInts(length); + } + + void testLong(FuzzedDataProvider data) { + data.consumeLong(); + } + + void testLongMinMax(FuzzedDataProvider data) { + long min = data.consumeLong(); + long max = data.consumeLong(); + if (min > max) { + return; + } + data.consumeLong(min, max); + } + + void testLongs(FuzzedDataProvider data) { + int length = data.consumeInt(); + if (length < 0) { + return; + } + data.consumeLongs(length); + } + + void testFloat(FuzzedDataProvider data) { + data.consumeFloat(); + } + + void testRegularFloat(FuzzedDataProvider data) { + float f = data.consumeRegularFloat(); + if (!Float.isFinite(f)) { + throw new RuntimeException("regular float has invalid value"); + } + } + + void testRegularFloatMinMax(FuzzedDataProvider data) { + float min = data.consumeFloat(); + float max = data.consumeFloat(); + if (!Float.isFinite(min) || !Float.isFinite(max)) { + return; + } + if (min > max) { + return; + } + float f = data.consumeRegularFloat(min, max); + if (!Float.isFinite(f)) { + throw new RuntimeException("regular float has invalid value"); + } + if (f < min) { + throw new RuntimeException("output value is smaller than min"); + } + if (f > max) { + throw new RuntimeException("output value is larger than max"); + } + } + + void testProbabilityFloat(FuzzedDataProvider data) { + float f = data.consumeProbabilityFloat(); + if (f < 0.0 || f > 1.0) { + throw new RuntimeException("probability float has value outside [0.0, 1.0]"); + } + } + + void testDouble(FuzzedDataProvider data) { + data.consumeDouble(); + } + + void testRegularDouble(FuzzedDataProvider data) { + double d = data.consumeRegularDouble(); + if (!Double.isFinite(d)) { + throw new RuntimeException("regular double has invalid value"); + } + } + + void testRegularDoubleMinMax(FuzzedDataProvider data) { + double min = data.consumeDouble(); + double max = data.consumeDouble(); + if (!Double.isFinite(min) || !Double.isFinite(max)) { + return; + } + if (min > max) { + return; + } + double d = data.consumeRegularDouble(min, max); + if (!Double.isFinite(d)) { + throw new RuntimeException("regular double has invalid value"); + } + if (d < min) { + throw new RuntimeException("output value is smaller than min"); + } + if (d > max) { + throw new RuntimeException("output value is larger than max"); + } + } + + void testProbabilityDouble(FuzzedDataProvider data) { + double d = data.consumeProbabilityDouble(); + if (d < 0.0 || d > 1.0) { + throw new RuntimeException("probability double is outside [0.0, 1.0]"); + } + } + + void testChar(FuzzedDataProvider data) { + data.consumeChar(); + } + + void testConsumeCharMinMax(FuzzedDataProvider data) { + char min = data.consumeChar(); + char max = data.consumeChar(); + if (min > max) { + return; + } + data.consumeChar(min, max); + } + + void testCharNoSurrogates(FuzzedDataProvider data) { + char c = data.consumeCharNoSurrogates(); + if (Character.isSurrogate(c)) { + throw new RuntimeException("character was a surrogate"); + } + } + + void testString(FuzzedDataProvider data) { + int length = data.consumeInt(); + if (length < 0) { + return; + } + data.consumeString(length); + } + + void testRemainingAsString(FuzzedDataProvider data) { + data.consumeRemainingAsString(); + } + + void testAsciiString(FuzzedDataProvider data) { + int length = data.consumeInt(); + if (length < 0) { + return; + } + String s = data.consumeAsciiString(length); + if (s.chars().anyMatch(c -> c >= 128)) { + throw new RuntimeException("ascii string contains character outside ascii range"); + } + } + + void testRemainingAsAsciiString(FuzzedDataProvider data) { + data.consumeRemainingAsAsciiString(); + } + + void testPickValueCollection(FuzzedDataProvider data) { + int length = data.consumeShort(); + if (length <= 0) { + return; + } + ArrayList collection = new ArrayList<>(); + for (int i = 0; i < length; i++) { + collection.add(data.consumeInt()); + } + + data.pickValue(collection); + } + + void testPickValueArray(FuzzedDataProvider data) { + int length = data.consumeShort(); + if (length <= 0) { + return; + } + Integer[] collection = new Integer[length]; + for (int i = 0; i < length; i++) { + collection[i] = data.consumeInt(); + } + data.pickValue(collection); + } + + void testPickValueBoolean(FuzzedDataProvider data) { + int length = data.consumeShort(); + if (length <= 0) { + return; + } + boolean[] collection = new boolean[length]; + for (int i = 0; i < length; i++) { + collection[i] = data.consumeBoolean(); + } + data.pickValue(collection); + } + + void testPickValueByte(FuzzedDataProvider data) { + int length = data.consumeShort(); + if (length <= 0) { + return; + } + byte[] collection = new byte[length]; + for (int i = 0; i < length; i++) { + collection[i] = data.consumeByte(); + } + data.pickValue(collection); + } + + void testPickValueShort(FuzzedDataProvider data) { + int length = data.consumeShort(); + if (length <= 0) { + return; + } + short[] collection = new short[length]; + for (int i = 0; i < length; i++) { + collection[i] = data.consumeShort(); + } + data.pickValue(collection); + } + + void testPickValueInt(FuzzedDataProvider data) { + int length = data.consumeShort(); + if (length <= 0) { + return; + } + int[] collection = new int[length]; + for (int i = 0; i < length; i++) { + collection[i] = data.consumeInt(); + } + data.pickValue(collection); + } + + void testPickValueLong(FuzzedDataProvider data) { + int length = data.consumeShort(); + if (length <= 0) { + return; + } + long[] collection = new long[length]; + for (int i = 0; i < length; i++) { + collection[i] = data.consumeLong(); + } + data.pickValue(collection); + } + + void testPickValueDouble(FuzzedDataProvider data) { + int length = data.consumeShort(); + if (length <= 0) { + return; + } + double[] collection = new double[length]; + for (int i = 0; i < length; i++) { + collection[i] = data.consumeDouble(); + } + data.pickValue(collection); + } + + void testPickValueFloat(FuzzedDataProvider data) { + int length = data.consumeShort(); + if (length <= 0) { + return; + } + float[] collection = new float[length]; + for (int i = 0; i < length; i++) { + collection[i] = data.consumeFloat(); + } + data.pickValue(collection); + } + + void testPickValueChar(FuzzedDataProvider data) { + int length = data.consumeShort(); + if (length <= 0) { + return; + } + char[] collection = new char[length]; + for (int i = 0; i < length; i++) { + collection[i] = data.consumeChar(); + } + data.pickValue(collection); + } + + void testPickValuesCollection(FuzzedDataProvider data) { + int length = data.consumeShort(); + if (length <= 0) { + return; + } + int numValues = data.consumeShort(); + if (numValues > length) { + return; + } + ArrayList collection = new ArrayList<>(); + for (int i = 0; i < length; i++) { + collection.add(data.consumeInt()); + } + + data.pickValues(collection, numValues); + } + + void testPickValuesArray(FuzzedDataProvider data) { + int length = data.consumeShort(); + if (length <= 0) { + return; + } + int numValues = data.consumeShort(); + if (numValues > length) { + return; + } + Integer[] collection = new Integer[length]; + + for (int i = 0; i < length; i++) { + collection[i] = data.consumeInt(); + } + data.pickValues(collection, numValues); + } +} diff --git a/src/main/java/com/code_intelligence/jazzer/driver/BUILD.bazel b/src/main/java/com/code_intelligence/jazzer/driver/BUILD.bazel index 0d2efb002..6b5f3870a 100644 --- a/src/main/java/com/code_intelligence/jazzer/driver/BUILD.bazel +++ b/src/main/java/com/code_intelligence/jazzer/driver/BUILD.bazel @@ -125,8 +125,11 @@ java_jni_library( java_jni_library( name = "fuzzed_data_provider_impl", srcs = ["FuzzedDataProviderImpl.java"], - native_libs = ["//src/main/native/com/code_intelligence/jazzer/driver:jazzer_fuzzed_data_provider"], + native_libs = [ + "//src/main/native/com/code_intelligence/jazzer/driver:jazzer_fuzzed_data_provider", + ], visibility = [ + "//selffuzz/src/test/java/com/code_intelligence/selffuzz/driver:__subpackages__", "//src:__subpackages__", ], deps = [ diff --git a/src/main/native/com/code_intelligence/jazzer/driver/BUILD.bazel b/src/main/native/com/code_intelligence/jazzer/driver/BUILD.bazel index ea199635a..3e95ea114 100644 --- a/src/main/native/com/code_intelligence/jazzer/driver/BUILD.bazel +++ b/src/main/native/com/code_intelligence/jazzer/driver/BUILD.bazel @@ -71,7 +71,10 @@ cc_library( cc_library( name = "fuzzed_data_provider", - srcs = ["fuzzed_data_provider.cpp"], + srcs = [ + "com_code_intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl.h", + "fuzzed_data_provider.cpp", + ], visibility = [ "//launcher:__pkg__", ], @@ -85,8 +88,13 @@ cc_library( cc_jni_library( name = "jazzer_fuzzed_data_provider", platforms = MULTI_PLATFORM, - visibility = ["//src/main/java/com/code_intelligence/jazzer/driver:__pkg__"], - deps = [":fuzzed_data_provider"], + visibility = [ + "//selffuzz/src/test/java/com/code_intelligence/selffuzz/driver:__subpackages__", + "//src/main/java/com/code_intelligence/jazzer/driver:__pkg__", + ], + deps = [ + ":fuzzed_data_provider", + ], ) cc_library( diff --git a/src/main/native/com/code_intelligence/jazzer/driver/com_code_intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl.h b/src/main/native/com/code_intelligence/jazzer/driver/com_code_intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl.h new file mode 100644 index 000000000..0491f40ba --- /dev/null +++ b/src/main/native/com/code_intelligence/jazzer/driver/com_code_intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl.h @@ -0,0 +1,356 @@ +/* + * Copyright 2023 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. + */ + +/* This file was originally generated by cc_jni_library(name = + jazzer_fuzzed_data_provider_impl) and copied here and modified + + Specifically it was taken from + `bazel-bin/src/main/java/com/code_intelligence/jazzer/driver/fuzzed_data_provider_impl.hdrs.h/com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl.h` + and modified such that all symbol names now include `selffuzz` in order to + be usable by our selffuzzing library. Due to the shading of our class files, + the selffuzz code will attempt to load symbols with the new classpath which + otherwise don't exist. + + Normally the built jazzer jar will have a dylib (on Mac) in + `/com/code_intelligence/jazzer/driver/jazzer_fuzzed_data_provider_macos_aarch64/libjazzer_fuzzed_data_provider.dylib` + + FuzzedDataProviderImpl will load that with a call to + ``` + RulesJni.loadLibrary("jazzer_fuzzed_data_provider", + "/com/code_intelligence/jazzer/driver"); + ``` + which will look in a folder with that name plus architecture-specific bits + for a library to load. + + Our shading utility properly changes that into + ``` + RulesJni.loadLibrary("jazzer_fuzzed_data_provider", + "/com/code_intelligence/selffuzz/jazzer/driver"); + ``` + which is where that lib will be in the new jar and the shaded + FuzzedDataProviderImpl will load it but that library is not changed during + the shading so it will have the symbols defined at build time. When + FuzzedDataProviderImpl attempts to call + `Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_nativeInit`, + it will fail because the symbol does not exist. + + Duplicating and renaming the symbols via this header file and copying and + renaming `nativeInit` in `fuzzed_data_provider.cpp` means that both the + normal and shaded FuzzedDataProviderImpls will be able to work. It would + probably be possible to remove this with some more selective build rules when + building a selffuzz jar. +*/ +#include +/* Header for class com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + */ + +#ifndef _Included_com_code_intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl +#define _Included_com_code_intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: nativeInit + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_nativeInit( + JNIEnv *, jclass); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeBoolean + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeBoolean( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeBooleans + * Signature: (I)[Z + */ +JNIEXPORT jbooleanArray JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeBooleans( + JNIEnv *, jobject, jint); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeByte + * Signature: ()B + */ +JNIEXPORT jbyte JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeByte( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeShort + * Signature: ()S + */ +JNIEXPORT jshort JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeShort( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeShorts + * Signature: (I)[S + */ +JNIEXPORT jshortArray JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeShorts( + JNIEnv *, jobject, jint); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeInt + * Signature: ()I + */ +JNIEXPORT jint JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeInt( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeInts + * Signature: (I)[I + */ +JNIEXPORT jintArray JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeInts( + JNIEnv *, jobject, jint); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeLong + * Signature: ()J + */ +JNIEXPORT jlong JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeLong( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeLongs + * Signature: (I)[J + */ +JNIEXPORT jlongArray JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeLongs( + JNIEnv *, jobject, jint); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeFloat + * Signature: ()F + */ +JNIEXPORT jfloat JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeFloat( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeRegularFloat + * Signature: ()F + */ +JNIEXPORT jfloat JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeRegularFloat( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeProbabilityFloat + * Signature: ()F + */ +JNIEXPORT jfloat JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeProbabilityFloat( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeDouble + * Signature: ()D + */ +JNIEXPORT jdouble JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeDouble( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeRegularDouble + * Signature: ()D + */ +JNIEXPORT jdouble JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeRegularDouble( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeProbabilityDouble + * Signature: ()D + */ +JNIEXPORT jdouble JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeProbabilityDouble( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeChar + * Signature: ()C + */ +JNIEXPORT jchar JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeChar( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeCharNoSurrogates + * Signature: ()C + */ +JNIEXPORT jchar JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeCharNoSurrogates( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeAsciiString + * Signature: (I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeAsciiString( + JNIEnv *, jobject, jint); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeString + * Signature: (I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeString( + JNIEnv *, jobject, jint); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeRemainingAsAsciiString + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeRemainingAsAsciiString( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeRemainingAsString + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeRemainingAsString( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeBytes + * Signature: (I)[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeBytes( + JNIEnv *, jobject, jint); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeRemainingAsBytes + * Signature: ()[B + */ +JNIEXPORT jbyteArray JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeRemainingAsBytes( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: remainingBytes + * Signature: ()I + */ +JNIEXPORT jint JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_remainingBytes( + JNIEnv *, jobject); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeByteUnchecked + * Signature: (BB)B + */ +JNIEXPORT jbyte JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeByteUnchecked( + JNIEnv *, jobject, jbyte, jbyte); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeShortUnchecked + * Signature: (SS)S + */ +JNIEXPORT jshort JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeShortUnchecked( + JNIEnv *, jobject, jshort, jshort); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeCharUnchecked + * Signature: (CC)C + */ +JNIEXPORT jchar JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeCharUnchecked( + JNIEnv *, jobject, jchar, jchar); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeIntUnchecked + * Signature: (II)I + */ +JNIEXPORT jint JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeIntUnchecked( + JNIEnv *, jobject, jint, jint); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeLongUnchecked + * Signature: (JJ)J + */ +JNIEXPORT jlong JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeLongUnchecked( + JNIEnv *, jobject, jlong, jlong); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeRegularFloatUnchecked + * Signature: (FF)F + */ +JNIEXPORT jfloat JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeRegularFloatUnchecked( + JNIEnv *, jobject, jfloat, jfloat); + +/* + * Class: com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl + * Method: consumeRegularDoubleUnchecked + * Signature: (DD)D + */ +JNIEXPORT jdouble JNICALL +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_consumeRegularDoubleUnchecked( + JNIEnv *, jobject, jdouble, jdouble); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/main/native/com/code_intelligence/jazzer/driver/fuzzed_data_provider.cpp b/src/main/native/com/code_intelligence/jazzer/driver/fuzzed_data_provider.cpp index 7ea9c3445..7a2c0158e 100644 --- a/src/main/native/com/code_intelligence/jazzer/driver/fuzzed_data_provider.cpp +++ b/src/main/native/com/code_intelligence/jazzer/driver/fuzzed_data_provider.cpp @@ -51,6 +51,8 @@ #include #include "com_code_intelligence_jazzer_driver_FuzzedDataProviderImpl.h" +// see the header file for an explanation of why this is here +#include "com_code_intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl.h" namespace { @@ -690,3 +692,12 @@ Java_com_code_1intelligence_jazzer_driver_FuzzedDataProviderImpl_nativeInit( gDataPtrField = env->GetFieldID(clazz, "dataPtr", "J"); gRemainingBytesField = env->GetFieldID(clazz, "remainingBytes", "I"); } + +// duplicate nativeInit for selffuzz (see the selffuzz header file) +[[maybe_unused]] void +Java_com_code_1intelligence_selffuzz_jazzer_driver_FuzzedDataProviderImpl_nativeInit( + JNIEnv *env, jclass clazz) { + env->RegisterNatives(clazz, kFuzzedDataMethods, kNumFuzzedDataMethods); + gDataPtrField = env->GetFieldID(clazz, "dataPtr", "J"); + gRemainingBytesField = env->GetFieldID(clazz, "remainingBytes", "I"); +}