From 41e629718dc5e8002ec6ce82d908ab880bec5d46 Mon Sep 17 00:00:00 2001 From: aschaich <108736614+aschaich@users.noreply.github.com> Date: Sat, 17 Dec 2022 07:45:43 +0900 Subject: [PATCH] [netty] Add more fuzz targets (#9224) --- projects/netty/pom.xml | 4 +- .../io/netty/buffer/ByteBufUtilFuzzer.java | 122 ++++++++++++++++++ .../netty/buffer/LongLongHashMapFuzzer.java | 43 ++++++ .../cookie}/ServerCookieDecoderFuzzer.java | 3 +- .../main/java/ossfuzz/ByteBufUtilFuzzer.java | 59 --------- 5 files changed, 168 insertions(+), 63 deletions(-) create mode 100644 projects/netty/src/main/java/io/netty/buffer/ByteBufUtilFuzzer.java create mode 100644 projects/netty/src/main/java/io/netty/buffer/LongLongHashMapFuzzer.java rename projects/netty/src/main/java/{ossfuzz => io/netty/handler/codec/http/cookie}/ServerCookieDecoderFuzzer.java (94%) delete mode 100644 projects/netty/src/main/java/ossfuzz/ByteBufUtilFuzzer.java diff --git a/projects/netty/pom.xml b/projects/netty/pom.xml index 1b8ce3c72..bbb4749e3 100644 --- a/projects/netty/pom.xml +++ b/projects/netty/pom.xml @@ -11,8 +11,8 @@ 15 15 UTF-8 - 4.0.0-SNAPSHOT - ServerCookieDecoderFuzzer + 4.1.85.Final + io.netty.handler.codec.http.cookie.ServerCookieDecoderFuzzer diff --git a/projects/netty/src/main/java/io/netty/buffer/ByteBufUtilFuzzer.java b/projects/netty/src/main/java/io/netty/buffer/ByteBufUtilFuzzer.java new file mode 100644 index 000000000..e73e67997 --- /dev/null +++ b/projects/netty/src/main/java/io/netty/buffer/ByteBufUtilFuzzer.java @@ -0,0 +1,122 @@ +// Copyright 2022 Google LLC +// +// 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 io.netty.buffer; + +import java.nio.charset.Charset; +import java.nio.CharBuffer; + +import com.code_intelligence.jazzer.api.FuzzedDataProvider; + +public class ByteBufUtilFuzzer { + + private FuzzedDataProvider fuzzedDataProvider; + + public ByteBufUtilFuzzer(FuzzedDataProvider fuzzedDataProvider) { + this.fuzzedDataProvider = fuzzedDataProvider; + } + + byte[] getByteArray() { + int length = fuzzedDataProvider.consumeInt(0, fuzzedDataProvider.remainingBytes()); + return fuzzedDataProvider.consumeBytes(length); + } + + CharBuffer getCharBuffer() { + CharSequence charSequence = getCharSequence(); + CharBuffer charBuffer = CharBuffer.allocate(charSequence.length()); + charBuffer.put(charSequence.toString()); + return charBuffer; + } + + CharSequence getCharSequence() { + int length = fuzzedDataProvider.consumeInt(0, fuzzedDataProvider.remainingBytes()); + return fuzzedDataProvider.consumeString(length); + } + + int validIndex(ByteBuf buffer) { + int max = buffer.capacity(); + if (max != 0) { + max -= 1; // zero index is first element + } + return fuzzedDataProvider.consumeInt(0, max); + } + + int validLength(ByteBuf buffer, int start) { + int length = validIndex(buffer); + if (start + length > buffer.capacity()) { + length = buffer.capacity() - start; + length -= 1; // zero index is first element + } + return length; + } + + void test() { + try { + int fromIndex = fuzzedDataProvider.consumeInt(); + int toIndex = fuzzedDataProvider.consumeInt(); + byte value = fuzzedDataProvider.consumeByte(); + ByteBuf buffer = Unpooled.copiedBuffer(getByteArray()); + ByteBuf secondBuffer = Unpooled.copiedBuffer(getByteArray()); + if (buffer.capacity() != 0) { + // fromIndex and toIndex need to be valid indices, or indexOf + // will throw an out of bounds exception, which is not + // documented + ByteBufUtil.indexOf(buffer, Math.abs(fromIndex % buffer.capacity()), Math.abs(toIndex % buffer.capacity()), value); + } + ByteBufUtil.indexOf(secondBuffer, buffer); + ByteBufUtil.hexDump(buffer); + ByteBufUtil.hashCode(buffer); + + CharSequence charSequence = getCharSequence(); + if (buffer.capacity() >= buffer.writerIndex() + charSequence.length()) { + ByteBufUtil.writeUtf8(buffer, charSequence); + } + ByteBufUtil.writeUtf8(buffer.alloc(), charSequence); + ByteBufUtil.encodeString(buffer.alloc(), getCharBuffer(), Charset.forName("UTF-8")); + if(buffer.capacity() != 0) { + // again, out of bounds exceptions if the input array is empty + int index = validIndex(buffer); + int length = validLength(buffer, index); + ByteBufUtil.decodeString(buffer, index, length, Charset.forName("US-ASCII")); + CompositeByteBuf compositeByteBuf = Unpooled.compositeBuffer().addComponent(buffer); + ByteBufUtil.firstIndexOf(compositeByteBuf, index, length, value); + } + + ByteBufUtil.equals(buffer, secondBuffer); + ByteBufUtil.compare(buffer, secondBuffer); + ByteBufUtil.appendPrettyHexDump(new StringBuilder(charSequence), secondBuffer); + int index = validIndex(buffer); + int length = validLength(buffer, index); + ByteBufUtil.isText(buffer, Charset.forName("UTF-8")); + ByteBufUtil.isText(buffer,index, length, Charset.forName("UTF-8")); + ByteBufUtil.prettyHexDump(buffer); + ByteBufUtil.swapInt(fuzzedDataProvider.consumeInt()); + ByteBufUtil.swapLong(fuzzedDataProvider.consumeLong()); + ByteBufUtil.swapMedium(fuzzedDataProvider.consumeInt()); + ByteBufUtil.swapShort(fuzzedDataProvider.consumeShort()); + } catch (IllegalArgumentException e) { + + } catch (IllegalStateException e) { + + } + } + + public static void fuzzerTestOneInput(FuzzedDataProvider fuzzedDataProvider) { + ByteBufUtilFuzzer fixture = new ByteBufUtilFuzzer(fuzzedDataProvider); + fixture.test(); + } +} \ No newline at end of file diff --git a/projects/netty/src/main/java/io/netty/buffer/LongLongHashMapFuzzer.java b/projects/netty/src/main/java/io/netty/buffer/LongLongHashMapFuzzer.java new file mode 100644 index 000000000..a7bbf94cb --- /dev/null +++ b/projects/netty/src/main/java/io/netty/buffer/LongLongHashMapFuzzer.java @@ -0,0 +1,43 @@ +package io.netty.buffer; +import com.code_intelligence.jazzer.api.FuzzedDataProvider; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + + +public class LongLongHashMapFuzzer { + + private FuzzedDataProvider fuzzedDataProvider; + + public LongLongHashMapFuzzer(FuzzedDataProvider fuzzedDataProvider) { + this.fuzzedDataProvider = fuzzedDataProvider; + } + + void test() { + Map expected = new HashMap(); + LongLongHashMap actual = new LongLongHashMap(-1); + while (fuzzedDataProvider.remainingBytes() >= 9 /* sizeof(long) + sizeof(byte) */) { + long value = fuzzedDataProvider.consumeLong(); + if (expected.containsKey(value)) { + if (fuzzedDataProvider.consumeBoolean()) { + actual.remove(value); + expected.remove(value); + } else { + long v = expected.get(value); + actual.put(value, -v); + expected.put(value, -v); + } + } else { + actual.put(value, value); + expected.put(value, value); + } + } + } + + public static void fuzzerTestOneInput(FuzzedDataProvider fuzzedDataProvider) { + LongLongHashMapFuzzer fixture = new LongLongHashMapFuzzer(fuzzedDataProvider); + fixture.test(); + } +} \ No newline at end of file diff --git a/projects/netty/src/main/java/ossfuzz/ServerCookieDecoderFuzzer.java b/projects/netty/src/main/java/io/netty/handler/codec/http/cookie/ServerCookieDecoderFuzzer.java similarity index 94% rename from projects/netty/src/main/java/ossfuzz/ServerCookieDecoderFuzzer.java rename to projects/netty/src/main/java/io/netty/handler/codec/http/cookie/ServerCookieDecoderFuzzer.java index 5b046c29a..595eddadf 100644 --- a/projects/netty/src/main/java/ossfuzz/ServerCookieDecoderFuzzer.java +++ b/projects/netty/src/main/java/io/netty/handler/codec/http/cookie/ServerCookieDecoderFuzzer.java @@ -14,10 +14,9 @@ // //////////////////////////////////////////////////////////////////////////////// -package ossfuzz; +package io.netty.handler.codec.http.cookie; import com.code_intelligence.jazzer.api.FuzzedDataProvider; -import io.netty.handler.codec.http.cookie.ServerCookieDecoder; public class ServerCookieDecoderFuzzer { diff --git a/projects/netty/src/main/java/ossfuzz/ByteBufUtilFuzzer.java b/projects/netty/src/main/java/ossfuzz/ByteBufUtilFuzzer.java deleted file mode 100644 index 7a648fa76..000000000 --- a/projects/netty/src/main/java/ossfuzz/ByteBufUtilFuzzer.java +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2022 Google LLC -// -// 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 ossfuzz; - -import com.code_intelligence.jazzer.api.FuzzedDataProvider; -import io.netty.buffer.ByteBufUtil; -import io.netty.buffer.Unpooled; - -public class ByteBufUtilFuzzer { - - private FuzzedDataProvider fuzzedDataProvider; - - public ByteBufUtilFuzzer(FuzzedDataProvider fuzzedDataProvider) { - this.fuzzedDataProvider = fuzzedDataProvider; - - } - - void test() { - try { - var fromIndex = fuzzedDataProvider.consumeInt(); - var toIndex = fuzzedDataProvider.consumeInt(); - var value = fuzzedDataProvider.consumeByte(); - byte[] bytes = fuzzedDataProvider.consumeRemainingAsBytes(); - var buf = Unpooled.copiedBuffer(bytes); - if (bytes.length != 0) { - // fromIndex and toIndex need to be valid indices, or indexOf - // will throw an out of bounds exception, which is not - // documented - ByteBufUtil.indexOf(buf, Math.abs(fromIndex % bytes.length), Math.abs(toIndex % bytes.length), value); - } - - } catch (IllegalArgumentException e) { - - } - - } - - public static void fuzzerTestOneInput(FuzzedDataProvider fuzzedDataProvider) { - - ByteBufUtilFuzzer fixture = new ByteBufUtilFuzzer(fuzzedDataProvider); - fixture.test(); - } - -} \ No newline at end of file