aboutsummaryrefslogtreecommitdiff
path: root/examples/src/main/java/com/example
diff options
context:
space:
mode:
authorFabian Meumertzheim <meumertzheim@code-intelligence.com>2021-01-29 16:20:19 +0100
committerFabian Meumertzheim <meumertzheim@code-intelligence.com>2021-02-09 17:20:51 +0100
commit5246e52be3bf4427791000355cbef86626b43eca (patch)
treee0683ad15664f2c3deecf3a6ce8c56f2a9597d85 /examples/src/main/java/com/example
downloadjazzer-api-5246e52be3bf4427791000355cbef86626b43eca.tar.gz
Initial commit
Diffstat (limited to 'examples/src/main/java/com/example')
-rw-r--r--examples/src/main/java/com/example/ExampleFuzzer.java40
-rw-r--r--examples/src/main/java/com/example/ExampleFuzzerHooks.java30
-rw-r--r--examples/src/main/java/com/example/ExampleFuzzerWithNative.java35
-rw-r--r--examples/src/main/java/com/example/ExampleValueProfileFuzzer.java53
-rw-r--r--examples/src/main/java/com/example/FastJsonFuzzer.java32
-rw-r--r--examples/src/main/java/com/example/GifImageParserFuzzer.java34
-rw-r--r--examples/src/main/java/com/example/JacksonCborFuzzer.java36
-rw-r--r--examples/src/main/java/com/example/JpegImageParserFuzzer.java33
-rw-r--r--examples/src/main/java/com/example/JsonSanitizerFuzzer.java42
-rw-r--r--examples/src/main/java/com/example/TiffImageParserFuzzer.java33
-rw-r--r--examples/src/main/java/com/example/TurboJpegFuzzer.java61
11 files changed, 429 insertions, 0 deletions
diff --git a/examples/src/main/java/com/example/ExampleFuzzer.java b/examples/src/main/java/com/example/ExampleFuzzer.java
new file mode 100644
index 00000000..40dcb697
--- /dev/null
+++ b/examples/src/main/java/com/example/ExampleFuzzer.java
@@ -0,0 +1,40 @@
+// 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.example;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import java.security.SecureRandom;
+
+public class ExampleFuzzer {
+ public static void fuzzerInitialize() {
+ // Optional initialization to be run before the first call to fuzzerTestOneInput.
+ }
+
+ public static boolean fuzzerTestOneInput(FuzzedDataProvider data) {
+ String input = data.consumeRemainingAsString();
+ // Without the hook in ExampleFuzzerHooks.java, the value of random would change on every
+ // invocation, making it almost impossible to guess for the fuzzer.
+ long random = new SecureRandom().nextLong();
+ if (input.startsWith("magicstring" + random) && input.length() > 30
+ && input.charAt(25) == 'C') {
+ mustNeverBeCalled();
+ }
+ return false;
+ }
+
+ private static void mustNeverBeCalled() {
+ throw new IllegalStateException("mustNeverBeCalled has been called");
+ }
+}
diff --git a/examples/src/main/java/com/example/ExampleFuzzerHooks.java b/examples/src/main/java/com/example/ExampleFuzzerHooks.java
new file mode 100644
index 00000000..41f16635
--- /dev/null
+++ b/examples/src/main/java/com/example/ExampleFuzzerHooks.java
@@ -0,0 +1,30 @@
+// 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.example;
+
+import com.code_intelligence.jazzer.api.HookType;
+import com.code_intelligence.jazzer.api.MethodHook;
+import java.lang.invoke.MethodHandle;
+
+public class ExampleFuzzerHooks {
+ @MethodHook(type = HookType.REPLACE, targetClassName = "java.security.SecureRandom",
+ targetMethod = "nextLong", targetMethodDescriptor = "()J")
+ public static long
+ getRandomNumber(MethodHandle handle, Object thisObject, Object[] args, int hookId) {
+ return 4; // chosen by fair dice roll.
+ // guaranteed to be random.
+ // https://xkcd.com/221/
+ }
+}
diff --git a/examples/src/main/java/com/example/ExampleFuzzerWithNative.java b/examples/src/main/java/com/example/ExampleFuzzerWithNative.java
new file mode 100644
index 00000000..801e84ea
--- /dev/null
+++ b/examples/src/main/java/com/example/ExampleFuzzerWithNative.java
@@ -0,0 +1,35 @@
+// 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.example;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+
+public class ExampleFuzzerWithNative {
+ static {
+ System.loadLibrary("native");
+ }
+
+ public static boolean fuzzerTestOneInput(FuzzedDataProvider data) {
+ int val = data.consumeInt();
+ String stringData = data.consumeRemainingAsString();
+ if (val == 17759716 && stringData.length() > 10 && stringData.contains("jazzer")) {
+ // call native function which contains a crash
+ new ExampleFuzzerWithNative().parse(stringData);
+ }
+ return false;
+ }
+
+ private native boolean parse(String bytes);
+} \ No newline at end of file
diff --git a/examples/src/main/java/com/example/ExampleValueProfileFuzzer.java b/examples/src/main/java/com/example/ExampleValueProfileFuzzer.java
new file mode 100644
index 00000000..1eb55df0
--- /dev/null
+++ b/examples/src/main/java/com/example/ExampleValueProfileFuzzer.java
@@ -0,0 +1,53 @@
+// 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.example;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import java.util.Base64;
+
+public class ExampleValueProfileFuzzer {
+ private static String base64(byte[] input) {
+ return Base64.getEncoder().encodeToString(input);
+ }
+
+ private static long insecureEncrypt(long input) {
+ long key = 0xefe4eb93215cb6b0L;
+ return input ^ key;
+ }
+
+ public static boolean fuzzerTestOneInput(FuzzedDataProvider data) {
+ // Without -use_value_profile=1, the fuzzer gets stuck here as there is no direct correspondence
+ // between the input bytes and the compared string. With value profile, the fuzzer can guess the
+ // expected input byte by byte, which takes linear rather than exponential time.
+ if (base64(data.consumeBytes(6)).equals("SmF6emVy")) {
+ long[] plaintextBlocks = data.consumeLongs(2);
+ if (plaintextBlocks.length != 2)
+ return false;
+ if (insecureEncrypt(plaintextBlocks[0]) == 0x9fc48ee64d3dc090L) {
+ // Without --fake_pcs (enabled by default with -use_value_profile=1), the fuzzer would get
+ // stuck here as the value profile information for long comparisons would not be able to
+ // distinguish between this comparison and the one above.
+ if (insecureEncrypt(plaintextBlocks[1]) == 0x888a82ff483ad9c2L) {
+ mustNeverBeCalled();
+ }
+ }
+ }
+ return false;
+ }
+
+ private static void mustNeverBeCalled() {
+ throw new IllegalStateException("mustNeverBeCalled has been called");
+ }
+}
diff --git a/examples/src/main/java/com/example/FastJsonFuzzer.java b/examples/src/main/java/com/example/FastJsonFuzzer.java
new file mode 100644
index 00000000..5c203ffb
--- /dev/null
+++ b/examples/src/main/java/com/example/FastJsonFuzzer.java
@@ -0,0 +1,32 @@
+// 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.example;
+
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONException;
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+
+// Found the issues described in
+// https://github.com/alibaba/fastjson/issues/3631
+public class FastJsonFuzzer {
+ public static boolean fuzzerTestOneInput(FuzzedDataProvider data) {
+ try {
+ JSON.parse(data.consumeRemainingAsString());
+ } catch (JSONException e) {
+ return false;
+ }
+ return false;
+ }
+}
diff --git a/examples/src/main/java/com/example/GifImageParserFuzzer.java b/examples/src/main/java/com/example/GifImageParserFuzzer.java
new file mode 100644
index 00000000..276bdb84
--- /dev/null
+++ b/examples/src/main/java/com/example/GifImageParserFuzzer.java
@@ -0,0 +1,34 @@
+// 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.example;
+
+import java.io.IOException;
+import java.util.HashMap;
+import org.apache.commons.imaging.ImageReadException;
+import org.apache.commons.imaging.common.bytesource.ByteSourceArray;
+import org.apache.commons.imaging.formats.gif.GifImageParser;
+
+// Found https://issues.apache.org/jira/browse/IMAGING-277 and
+// https://issues.apache.org/jira/browse/IMAGING-278.
+public class GifImageParserFuzzer {
+ public static boolean fuzzerTestOneInput(byte[] input) {
+ try {
+ new GifImageParser().getBufferedImage(new ByteSourceArray(input), new HashMap<>());
+ } catch (IOException | ImageReadException e) {
+ return false;
+ }
+ return false;
+ }
+}
diff --git a/examples/src/main/java/com/example/JacksonCborFuzzer.java b/examples/src/main/java/com/example/JacksonCborFuzzer.java
new file mode 100644
index 00000000..3d847751
--- /dev/null
+++ b/examples/src/main/java/com/example/JacksonCborFuzzer.java
@@ -0,0 +1,36 @@
+// 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.example;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
+import java.io.IOException;
+
+// Reproduces https://github.com/FasterXML/jackson-dataformats-binary/issues/236 and
+// https://github.com/FasterXML/jackson-databind/pull/3032 if executed with
+// `--keep_going=3 -seed=2735196724`.
+public class JacksonCborFuzzer {
+ public static boolean fuzzerTestOneInput(byte[] input) {
+ CBORFactory factory = new CBORFactory();
+ ObjectMapper mapper = new ObjectMapper(factory);
+ mapper.enableDefaultTyping();
+ try {
+ mapper.readTree(input);
+ } catch (IOException e) {
+ return false;
+ }
+ return false;
+ }
+}
diff --git a/examples/src/main/java/com/example/JpegImageParserFuzzer.java b/examples/src/main/java/com/example/JpegImageParserFuzzer.java
new file mode 100644
index 00000000..4040daee
--- /dev/null
+++ b/examples/src/main/java/com/example/JpegImageParserFuzzer.java
@@ -0,0 +1,33 @@
+// 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.example;
+
+import java.io.IOException;
+import java.util.HashMap;
+import org.apache.commons.imaging.ImageReadException;
+import org.apache.commons.imaging.common.bytesource.ByteSourceArray;
+import org.apache.commons.imaging.formats.jpeg.JpegImageParser;
+
+// Found https://issues.apache.org/jira/browse/IMAGING-275.
+public class JpegImageParserFuzzer {
+ public static boolean fuzzerTestOneInput(byte[] input) {
+ try {
+ new JpegImageParser().getBufferedImage(new ByteSourceArray(input), new HashMap<>());
+ } catch (IOException | ImageReadException e) {
+ return false;
+ }
+ return false;
+ }
+}
diff --git a/examples/src/main/java/com/example/JsonSanitizerFuzzer.java b/examples/src/main/java/com/example/JsonSanitizerFuzzer.java
new file mode 100644
index 00000000..ef13f369
--- /dev/null
+++ b/examples/src/main/java/com/example/JsonSanitizerFuzzer.java
@@ -0,0 +1,42 @@
+// 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.example;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import com.google.gson.Gson;
+import com.google.gson.JsonElement;
+import com.google.json.JsonSanitizer;
+
+public class JsonSanitizerFuzzer {
+ public static boolean fuzzerTestOneInput(FuzzedDataProvider data) {
+ String input = data.consumeRemainingAsString();
+ String validJson;
+ try {
+ validJson = JsonSanitizer.sanitize(input, 60);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ // ArrayIndexOutOfBoundsException is expected if nesting depth is
+ // exceeded.
+ return false;
+ }
+ Gson gson = new Gson();
+ gson.fromJson(validJson, JsonElement.class);
+ if (validJson.contains("</script>") || validJson.contains("<script")
+ || validJson.contains("<!--") || validJson.contains("]]>")) {
+ System.out.println(validJson);
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/examples/src/main/java/com/example/TiffImageParserFuzzer.java b/examples/src/main/java/com/example/TiffImageParserFuzzer.java
new file mode 100644
index 00000000..6dd127c2
--- /dev/null
+++ b/examples/src/main/java/com/example/TiffImageParserFuzzer.java
@@ -0,0 +1,33 @@
+// 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.example;
+
+import java.io.IOException;
+import java.util.HashMap;
+import org.apache.commons.imaging.ImageReadException;
+import org.apache.commons.imaging.common.bytesource.ByteSourceArray;
+import org.apache.commons.imaging.formats.tiff.TiffImageParser;
+
+// Found https://issues.apache.org/jira/browse/IMAGING-276.
+public class TiffImageParserFuzzer {
+ public static boolean fuzzerTestOneInput(byte[] input) {
+ try {
+ new TiffImageParser().getBufferedImage(new ByteSourceArray(input), new HashMap<>());
+ } catch (IOException | ImageReadException e) {
+ return false;
+ }
+ return false;
+ }
+}
diff --git a/examples/src/main/java/com/example/TurboJpegFuzzer.java b/examples/src/main/java/com/example/TurboJpegFuzzer.java
new file mode 100644
index 00000000..0a0059e4
--- /dev/null
+++ b/examples/src/main/java/com/example/TurboJpegFuzzer.java
@@ -0,0 +1,61 @@
+// 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.example;
+
+import com.code_intelligence.jazzer.api.FuzzedDataProvider;
+import org.libjpegturbo.turbojpeg.TJ;
+import org.libjpegturbo.turbojpeg.TJDecompressor;
+import org.libjpegturbo.turbojpeg.TJException;
+import org.libjpegturbo.turbojpeg.TJTransform;
+import org.libjpegturbo.turbojpeg.TJTransformer;
+
+public class TurboJpegFuzzer {
+ static byte[] buffer = new byte[128 * 128 * 4];
+
+ public static void fuzzerInitialize() throws TJException {
+ // Trigger an early load of the native library to show the coverage counters stats in libFuzzer.
+ new TJDecompressor();
+ }
+
+ public static boolean fuzzerTestOneInput(FuzzedDataProvider data) {
+ try {
+ int flagsDecompress = data.consumeInt();
+ int flagsTransform = data.consumeInt();
+ int pixelFormat = data.consumeInt(TJ.PF_RGB, TJ.PF_CMYK);
+ // Specify explicit small target width/height so that we can reuse a
+ // fixed-size buffer.
+ int desiredWidth = data.consumeInt(1, 128);
+ int desiredHeight = data.consumeInt(1, 128);
+ int transformOp = data.consumeInt(TJTransform.OP_NONE, TJTransform.OP_ROT270);
+ int transformOptions = data.consumeInt();
+ int transformWidth = data.consumeBoolean() ? 128 : 64;
+ int transformHeight = data.consumeBoolean() ? 128 : 64;
+ TJDecompressor tjd;
+ if (data.consumeBoolean()) {
+ TJTransformer tjt = new TJTransformer(data.consumeRemainingAsBytes());
+ TJTransform tjf = new TJTransform(
+ 0, 0, transformWidth, transformHeight, transformOp, transformOptions, null);
+ tjd = tjt.transform(new TJTransform[] {tjf}, flagsTransform)[0];
+ } else {
+ tjd = new TJDecompressor(data.consumeRemainingAsBytes());
+ }
+ tjd.decompress(buffer, 0, 0, desiredWidth, 0, desiredHeight, pixelFormat, flagsDecompress);
+ } catch (Exception e) {
+ // We are not looking for Java exceptions, but segfaults and ASan reports.
+ return false;
+ }
+ return false;
+ }
+}