]> git.ipfire.org Git - thirdparty/zstd.git/commitdiff
[Fuzz] Improve data generation #1723
authorDario Pavlovic <dariop@fb.com>
Mon, 9 Sep 2019 15:43:22 +0000 (08:43 -0700)
committerDario Pavlovic <dariop@fb.com>
Mon, 9 Sep 2019 15:43:22 +0000 (08:43 -0700)
tests/fuzz/Makefile
tests/fuzz/README.md
tests/fuzz/fuzz_data_producer.c [new file with mode: 0644]
tests/fuzz/fuzz_data_producer.h [new file with mode: 0644]
tests/fuzz/simple_decompress.c

index 08dedd66f22adebaaa20ff21e9851fb3d2de4f4f..83837e620f719545e3effa0627a1d09ab68e3539 100644 (file)
@@ -40,8 +40,8 @@ FUZZ_LDFLAGS := -pthread $(LDFLAGS)
 FUZZ_ARFLAGS := $(ARFLAGS)
 FUZZ_TARGET_FLAGS = $(FUZZ_CPPFLAGS) $(FUZZ_CXXFLAGS) $(FUZZ_LDFLAGS)
 
-FUZZ_HEADERS := fuzz_helpers.h fuzz.h zstd_helpers.h
-FUZZ_SRC := $(PRGDIR)/util.c zstd_helpers.c
+FUZZ_HEADERS := fuzz_helpers.h fuzz.h zstd_helpers.h fuzz_data_producer.h
+FUZZ_SRC := $(PRGDIR)/util.c zstd_helpers.c fuzz_data_producer.c
 
 ZSTDCOMMON_SRC := $(ZSTDDIR)/common/*.c
 ZSTDCOMP_SRC   := $(ZSTDDIR)/compress/*.c
index 856a57f82d8bdf6bf774dbd92dee2f796be321a2..71afa40631a16149f5786ed8e53c8771f9165910 100644 (file)
@@ -90,7 +90,7 @@ CC=afl-clang CXX=afl-clang++ ./fuzz.py build all --enable-asan --enable-ubsan
 
 ## Regression Testing
 
-The regression rest supports the `all` target to run all the fuzzers in one
+The regression test supports the `all` target to run all the fuzzers in one
 command.
 
 ```
diff --git a/tests/fuzz/fuzz_data_producer.c b/tests/fuzz/fuzz_data_producer.c
new file mode 100644 (file)
index 0000000..a083f63
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ */
+
+#include "fuzz_data_producer.h"
+
+struct FUZZ_dataProducer_s{
+  const uint8_t *data;
+  size_t size;
+};
+
+FUZZ_dataProducer_t *FUZZ_dataProducer_create(const uint8_t *data, size_t size) {
+    FUZZ_dataProducer_t *producer = malloc(sizeof(FUZZ_dataProducer_t));
+
+    FUZZ_ASSERT(producer != NULL);
+
+    producer->data = data;
+    producer->size = size;
+    return producer;
+}
+
+void FUZZ_dataProducer_free(FUZZ_dataProducer_t *producer) { free(producer); }
+
+uint32_t FUZZ_dataProducer_uint32Range(FUZZ_dataProducer_t *producer, uint32_t min,
+                                  uint32_t max) {
+    FUZZ_ASSERT(min <= max);
+
+    uint32_t range = max - min;
+    uint32_t rolling = range;
+    uint32_t result = 0;
+
+    while (rolling > 0 && producer->size > 0) {
+      uint8_t next = *(producer->data + producer->size - 1);
+      producer->size -= 1;
+      result = (result << 8) | next;
+      rolling >>= 8;
+    }
+
+    if (range == 0xffffffff) {
+      return result;
+    }
+
+    return min + result % (range + 1);
+}
+
+uint32_t FUZZ_dataProducer_uint32(FUZZ_dataProducer_t *producer) {
+  return FUZZ_dataProducer_uint32Range(producer, 0, 0xffffffff);
+}
+
+size_t FUZZ_dataProducer_remainingBytes(FUZZ_dataProducer_t *producer){
+    return producer->size;
+}
diff --git a/tests/fuzz/fuzz_data_producer.h b/tests/fuzz/fuzz_data_producer.h
new file mode 100644 (file)
index 0000000..4a12e13
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016-present, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under both the BSD-style license (found in the
+ * LICENSE file in the root directory of this source tree) and the GPLv2 (found
+ * in the COPYING file in the root directory of this source tree).
+ */
+
+/**
+ * Helper APIs for generating random data from input data stream.
+ */
+
+#ifndef FUZZ_DATA_PRODUCER_H
+#define FUZZ_DATA_PRODUCER_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "fuzz_helpers.h"
+
+/* Struct used for maintaining the state of the data */
+typedef struct FUZZ_dataProducer_s FUZZ_dataProducer_t;
+
+/* Returns a data producer state struct. Use for producer initialization. */
+FUZZ_dataProducer_t *FUZZ_dataProducer_create(const uint8_t *data, size_t size);
+
+/* Frees the data producer */
+void FUZZ_dataProducer_free(FUZZ_dataProducer_t *producer);
+
+/* Returns value between [min, max] */
+uint32_t FUZZ_dataProducer_uint32Range(FUZZ_dataProducer_t *producer, uint32_t min,
+                                  uint32_t max);
+
+/* Returns a uint32 value */
+uint32_t FUZZ_dataProducer_uint32(FUZZ_dataProducer_t *producer);
+
+/* Returns the size of the remaining bytes of data in the producer */
+size_t FUZZ_dataProducer_remainingBytes(FUZZ_dataProducer_t *producer);
+
+#endif // FUZZ_DATA_PRODUCER_H
index af3f302bb092d350a014fac3acff99373144ab56..56ebb93e6ecdcaa31b453125c535ed06397acebd 100644 (file)
 #include <stdio.h>
 #include "fuzz_helpers.h"
 #include "zstd.h"
+#include "fuzz_data_producer.h"
 
 static ZSTD_DCtx *dctx = NULL;
 
 int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
 {
 
-    uint32_t seed = FUZZ_seed(&src, &size);
+    FUZZ_dataProducer_t *producer = FUZZ_dataProducer_create(src, size);
     int i;
     if (!dctx) {
         dctx = ZSTD_createDCtx();
@@ -31,13 +32,15 @@ int LLVMFuzzerTestOneInput(const uint8_t *src, size_t size)
     }
     /* Run it 10 times over 10 output sizes. Reuse the context. */
     for (i = 0; i < 10; ++i) {
-        size_t const bufSize = FUZZ_rand32(&seed, 0, 2 * size);
+        size_t const bufSize = FUZZ_dataProducer_uint32Range(producer, 0, 2 * size);
         void* rBuf = malloc(bufSize);
         FUZZ_ASSERT(rBuf);
         ZSTD_decompressDCtx(dctx, rBuf, bufSize, src, size);
         free(rBuf);
     }
 
+    FUZZ_dataProducer_free(producer);
+
 #ifndef STATEFUL_FUZZING
     ZSTD_freeDCtx(dctx); dctx = NULL;
 #endif