[ovs-dev] [PATCH] oss-fuzz: Move oss-fuzz test harnesses and fuzzer configs to ovs source repo

Ben Pfaff blp at ovn.org
Mon Jul 9 21:18:31 UTC 2018


On Sat, Jul 07, 2018 at 12:12:11AM +0200, Bhargava Shastry wrote:
> > Is that the preferred way to do it?  It seems a little ad hoc.  Another
> > way would be to add a target to the OVS build tree, so that the script
> > could just become something like
> > 
> >         ./boot.sh && ./configure && make -j$(nproc) tests/oss-fuzz/fuzzer
> > 
> > or whatever.
> 
> This is cleaner and my preference as well. How do I go about doing this?
> 
> > 
> > But, maybe this ad hoc build method is conventional for oss-fuzz?  I'm
> > not familiar with their usual processes.
> 
> I don't think Google cares how targets are built although a lot of
> targets are currently built in an ad-hoc way.
> 
> > Well, either they have to have #include <config.h> or we need to
> > blacklist these files, one or the other.  The former is probably
> > harmless and possibly helpful.
> 
> Let's add a make target for oss-fuzz and and everything that is needed
> to get that done. I suppose this means I add a #include <config.h> as
> the first line of each of the fuzz test harnesses?
> 
> >>> The new files need to get mentioned in an automake.mk, at least in
> >>> EXTRA_DIST, to ensure that "make dist" will put them into the tarball:
> >>>
> >>>     The following files are in git but not the distribution:
> >>>     tests/oss-fuzz/config/flow_extract_fuzzer.options
> >>>     tests/oss-fuzz/config/json_parser_fuzzer.options
> >>>     tests/oss-fuzz/config/ofp_print_fuzzer.options
> >>>     tests/oss-fuzz/config/ovs.dict
> >>>     tests/oss-fuzz/flow_extract_target.c
> >>>     tests/oss-fuzz/json_parser_target.c
> >>>     tests/oss-fuzz/ofp_print_target.c
> >>
> >> There are several automake files to choose from. How do I do this?
> > 
> > I'd add a new tests/oss-fuzz/automake.mk and then include that in
> > tests/automake.mk.
> 
> I am not sure about this step. I will get back to you once we have a
> make target ready.

Here's a revised patch that does most of the work I requested.  You can
run "make oss-fuzz-targets" to build the targets.  You probably need to
specify LDFLAGS=... to link against additional libraries though.

--8<--------------------------cut here-------------------------->8--

From: Bhargava Shastry <bshastry at sec.t-labs.tu-berlin.de>
Date: Thu, 5 Jul 2018 15:32:53 -0700
Subject: [PATCH] oss-fuzz: Move oss-fuzz test harnesses and fuzzer configs to
 ovs source repo

Signed-off-by: Ben Pfaff <blp at ovn.org>
---
 Makefile.am                                       |   1 +
 tests/automake.mk                                 |   2 +
 tests/oss-fuzz/automake.mk                        |  21 ++
 tests/oss-fuzz/config/flow_extract_fuzzer.options |   2 +
 tests/oss-fuzz/config/json_parser_fuzzer.options  |   2 +
 tests/oss-fuzz/config/ofp_print_fuzzer.options    |   3 +
 tests/oss-fuzz/config/ovs.dict                    | 293 ++++++++++++++++++++++
 tests/oss-fuzz/flow_extract_target.c              |  14 ++
 tests/oss-fuzz/fuzzer.h                           |   9 +
 tests/oss-fuzz/json_parser_target.c               |  57 +++++
 tests/oss-fuzz/ofp_print_target.c                 |  50 ++++
 11 files changed, 454 insertions(+)
 create mode 100644 tests/oss-fuzz/automake.mk
 create mode 100644 tests/oss-fuzz/config/flow_extract_fuzzer.options
 create mode 100644 tests/oss-fuzz/config/json_parser_fuzzer.options
 create mode 100644 tests/oss-fuzz/config/ofp_print_fuzzer.options
 create mode 100644 tests/oss-fuzz/config/ovs.dict
 create mode 100644 tests/oss-fuzz/flow_extract_target.c
 create mode 100644 tests/oss-fuzz/fuzzer.h
 create mode 100644 tests/oss-fuzz/json_parser_target.c
 create mode 100644 tests/oss-fuzz/ofp_print_target.c

diff --git a/Makefile.am b/Makefile.am
index e02799a90fab..ffbd051261b1 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -102,6 +102,7 @@ dist_pkgdata_SCRIPTS =
 dist_sbin_SCRIPTS =
 dist_scripts_SCRIPTS =
 dist_scripts_DATA =
+EXTRA_PROGRAMS =
 INSTALL_DATA_LOCAL =
 UNINSTALL_LOCAL =
 man_MANS =
diff --git a/tests/automake.mk b/tests/automake.mk
index 8224e5a4a22d..b7be1ea65811 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -475,3 +475,5 @@ clean-pki:
 	rm -f tests/pki/stamp
 	rm -rf tests/pki
 endif
+
+include tests/oss-fuzz/automake.mk
diff --git a/tests/oss-fuzz/automake.mk b/tests/oss-fuzz/automake.mk
new file mode 100644
index 000000000000..d64b6986fc5e
--- /dev/null
+++ b/tests/oss-fuzz/automake.mk
@@ -0,0 +1,21 @@
+OSS_FUZZ_TARGETS = \
+	tests/oss-fuzz/flow_extract_target \
+	tests/oss-fuzz/json_parser_target \
+	tests/oss-fuzz/ofp_print_target
+EXTRA_PROGRAMS += $(OSS_FUZZ_TARGETS)
+oss-fuzz-targets: $(OSS_FUZZ_TARGETS)
+
+tests_oss_fuzz_flow_extract_target_SOURCES = tests/oss-fuzz/flow_extract_target.c
+tests_oss_fuzz_flow_extract_target_LDADD = lib/libopenvswitch.la
+
+tests_oss_fuzz_json_parser_target_SOURCES = tests/oss-fuzz/json_parser_target.c
+tests_oss_fuzz_json_parser_target_LDADD = lib/libopenvswitch.la
+
+tests_oss_fuzz_ofp_print_target_SOURCES = tests/oss-fuzz/ofp_print_target.c
+tests_oss_fuzz_ofp_print_target_LDADD = lib/libopenvswitch.la
+
+EXTRA_DIST += \
+	tests/oss-fuzz/config/flow_extract_fuzzer.options \
+	tests/oss-fuzz/config/json_parser_fuzzer.options \
+	tests/oss-fuzz/config/ofp_print_fuzzer.options \
+	tests/oss-fuzz/config/ovs.dict
diff --git a/tests/oss-fuzz/config/flow_extract_fuzzer.options b/tests/oss-fuzz/config/flow_extract_fuzzer.options
new file mode 100644
index 000000000000..7a77aaf0462a
--- /dev/null
+++ b/tests/oss-fuzz/config/flow_extract_fuzzer.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+dict = ovs.dict
diff --git a/tests/oss-fuzz/config/json_parser_fuzzer.options b/tests/oss-fuzz/config/json_parser_fuzzer.options
new file mode 100644
index 000000000000..8d3739a53fa2
--- /dev/null
+++ b/tests/oss-fuzz/config/json_parser_fuzzer.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+dict = json.dict
diff --git a/tests/oss-fuzz/config/ofp_print_fuzzer.options b/tests/oss-fuzz/config/ofp_print_fuzzer.options
new file mode 100644
index 000000000000..7f117292e62d
--- /dev/null
+++ b/tests/oss-fuzz/config/ofp_print_fuzzer.options
@@ -0,0 +1,3 @@
+[libfuzzer]
+close_fd_mask = 3
+dict = ovs.dict
diff --git a/tests/oss-fuzz/config/ovs.dict b/tests/oss-fuzz/config/ovs.dict
new file mode 100644
index 000000000000..243b243ab42a
--- /dev/null
+++ b/tests/oss-fuzz/config/ovs.dict
@@ -0,0 +1,293 @@
+"0.2"
+"ADD_SUBSCRIBE"
+"-cbc"
+"CLEARSUB"
+"CLIENT"
+"GIMME"
+"GIMMEDEFS"
+"GIMMESTATS"
+"HM"
+"-hmac96"
+"HM_CTL"
+"HM_STAT"
+"HMST_CLIENT"
+"LOGIN"
+"\\MAILSLOT\\BROWSE"
+"NET-ANNOUNCED"
+"NET-VISIBLE"
+"-nodefs"
+"NONE"
+"OPSTAFF"
+"\\PIPE\\LANMAN"
+"public"
+"REALM"
+"REALM-ANNOUNCED"
+"REALM-VISIBLE"
+"REQ_SUBSCRIBE"
+"RLM_SUBSCRIBE"
+"RLM_UNSUBSCRIBE"
+"SENT"
+" %ssub%s"
+"SUBSCRIBE"
+"SUBSCRIBE_NODEFS"
+"un"
+"UNSUBSCRIBE"
+"USER_FLUSH"
+"USER_HIDE"
+"USER_LOCATE"
+"USER_UNHIDE"
+"WG_CTL"
+"\x01\x00"
+"\x01\x00\x00"
+"\x01\x00\x01"
+"\x01\x00\x02"
+"\x01\x00\x03"
+"\x01\x00\x05"
+"\x01\x01"
+"\x01\x02"
+"\x01\x03"
+"\x01\x04"
+"\x01\x05"
+"\x01\x07"
+"\x01\x0B"
+"\x01\x0C"
+"\x01\x10"
+"\x01\x11"
+"\x01\x12"
+"\x01\x13"
+"\x01\x14"
+"\x01\x15"
+"\x01\x16"
+"\x01\xE8\x48"
+"\x01\xF4"
+"\x01\xF5"
+"\x01\xF6"
+"\x01\xF7"
+"\x01\xF8"
+"\x01\xF9"
+"\x01\xFA"
+"\x01\xFB"
+"\x01\xFC"
+"\x01\xFD"
+"\x01\xFE"
+"\x01\xFF"
+"\x02\x00"
+"\x02\x00\x00"
+"\x02\x01"
+"\x02\x02"
+"\x02\x03"
+"\x02\x04"
+"\x02\x05"
+"\x02\x06"
+"\x02\x07"
+"\x02\x08"
+"\x02\x09"
+"\x02\x0C"
+"\x02\x0E"
+"\x02\x0F"
+"\x02\x11"
+"\x02\x12"
+"\x02\x58"
+"\x02\x81"
+"\x02\x83"
+"\x03\x00"
+"\x03\x01"
+"\x03\x02"
+"\x03\x03"
+"\x03\x06"
+"\x03\xE8"
+"\x03\xE9"
+"\x03\xEA"
+"\x03\xEB"
+"\x03\xEC"
+"\x03\xED"
+"\x03\xEE"
+"\x03\xEF"
+"\x03\xF0"
+"\x03\xF1"
+"\x03\xF2"
+"\x03\xF3"
+"\x03\xF4"
+"\x03\xFF\xFF\xFF"
+"\x04\x00"
+"\x04\x00\x00"
+"\x04\x01"
+"\x04\x02"
+"\x04\x03"
+"\x04\x04"
+"\x04\x51"
+"\x04\x52"
+"\x04\x53"
+"\x04\x55"
+"\x04\x56"
+"\x05\x00"
+"\x05\x01"
+"\x05\x02"
+"\x05\x03"
+"\x05\x53"
+"\x05\xCC"
+"\x05\xDC"
+"\x06\x00"
+"\x06\x01"
+"\x06\xCF"
+"\x07\x07"
+"\x07\xC1"
+"\x07\xFF"
+"\x08\x00"
+"\x08\x00\x00\x00"
+"\x08\x00\x07"
+"\x08\x01"
+"\x08\x06"
+"\x08\x38\x00\x00"
+"\x0A\x00\xB1"
+"\x0C\x01"
+"\x0C\x02"
+"\x0C\x03"
+"\x0C\x04"
+"\x0C\x05"
+"\x0C\x06"
+"\x0C\x08"
+"\x0D\x80"
+"\x0E\x00"
+"\x0E\x10"
+"\x0E\xC8"
+"\x0E\xC9"
+"\x0F\x42\x40"
+"\x0F\xFF"
+"\x10\x00"
+"\x11\x11"
+"\x11\xD7"
+"\x12\x0F"
+"\x12\xBB"
+"\x1A\x30"
+"\x1A\x31"
+"\x1A\x32"
+"\x1B\x21"
+"\x1B\x58"
+"\x1B\x59"
+"\x1B\x5A"
+"\x1B\x5B"
+"\x1B\x5C"
+"\x1B\x5D"
+"\x1B\x5F"
+"\x1B\x61"
+"\x1F\x00"
+"\x1F\x40"
+"\x1F\xFF"
+"\x1F\xFF\xFF"
+"\x20\x00"
+"\x20\x03"
+"\x20\x04"
+"\x27\x10"
+"\x27\x13"
+"\x2F\xBF"
+"\x35\x00\x00"
+"\x3C\x13"
+"\x40\x00"
+"\x40\x04"
+"\x40\x80"
+"\x47\x00\x06\x01"
+"\x4E\x20"
+"\x4E\x21"
+"\x4E\x22"
+"\x4E\x23"
+"\x4E\x24"
+"\x4E\x25"
+"\x4E\x26"
+"\x4E\x27"
+"\x4E\x28"
+"\x4E\x29"
+"\x4E\x2A"
+"\x4E\x2C"
+"\x60\x00"
+"\x60\x01"
+"\x60\x02"
+"\x60\x03"
+"\x60\x04"
+"\x60\x07"
+"\x7F\xFF"
+"\x7F\xFF\xFF"
+"\x80\x00"
+"\x80\x00\x00\x00"
+"\x80\x01"
+"\x80\x05"
+"\x80\x0A"
+"\x80\x21"
+"\x80\x21\x10\x01"
+"\x80\x21\x10\x02"
+"\x80\x23"
+"\x80\x35"
+"\x80\x57"
+"\x80\x9B"
+"\x80\xC2"
+"\x80\xF3"
+"\x80\xFD"
+"\x81\x00"
+"\x81\x37"
+"\x82\x81"
+"\x83\xAA\x7E\x80"
+"\x85\xBE"
+"\x86\xDD"
+"\x88\x08"
+"\x88\x09"
+"\x88\x0B"
+"\x88\x47"
+"\x88\x48"
+"\x88\x63"
+"\x88\x64"
+"\x88\x6F"
+"\x88\x70"
+"\x88\x8E"
+"\x88\x99"
+"\x88\xA2"
+"\x88\xA8"
+"\x88\xCA"
+"\x88\xCC"
+"\x89\x02"
+"\x89\x3A"
+"\x89\x47"
+"\x90\x00"
+"\x91\x00"
+"\xA0\x00"
+"\xAB\xCD"
+"\xB0\x00"
+"\xC0\x00\x00\x00"
+"\xC0\x21"
+"\xC0\x23"
+"\xC0\x25"
+"\xC0\x27"
+"\xC0\x2B"
+"\xC0\x2D"
+"\xC1\x23"
+"\xC2\x23"
+"\xC2\x27"
+"\xDA\xDA"
+"\xE0\x00"
+"\xE0\x00\x00\x00"
+"\xF0\x00\x00\x00"
+"\xF1\x0A"
+"\xF9\x89"
+"\xFC\x00"
+"\xFD\xE9"
+"\xFE\xFE"
+"\xFF\x00"
+"\xFF\x00\x00"
+"\xFF\x00\x00\x00"
+"\xFF\xF0"
+"\xFF\xF8"
+"\xFF\xFD"
+"\xFF\xFE"
+"\xFF\xFF"
+"\xFF\xFF\x00\x00"
+"\xFF\xFF\xF0\x00"
+"\xFF\xFF\xFF\x00"
+"\xFF\xFF\xFF\x01"
+"\xFF\xFF\xFF\x02"
+"\xFF\xFF\xFF\x03"
+"\xFF\xFF\xFF\xEF"
+"\xFF\xFF\xFF\xFD"
+"\xFF\xFF\xFF\xFE"
+"\xFF\xFF\xFF\xFF"
+"ZEPH"
+"ZEPHYR_ADMIN"
+"ZEPHYR_CTL"
diff --git a/tests/oss-fuzz/flow_extract_target.c b/tests/oss-fuzz/flow_extract_target.c
new file mode 100644
index 000000000000..38456614f551
--- /dev/null
+++ b/tests/oss-fuzz/flow_extract_target.c
@@ -0,0 +1,14 @@
+#include <config.h>
+#include "fuzzer.h"
+#include "dp-packet.h"
+#include "flow.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+    struct dp_packet packet;
+    struct flow flow;
+
+    dp_packet_use_const(&packet, data, size);
+    flow_extract(&packet, &flow);
+    return 0;
+}
diff --git a/tests/oss-fuzz/fuzzer.h b/tests/oss-fuzz/fuzzer.h
new file mode 100644
index 000000000000..f87ae59e9185
--- /dev/null
+++ b/tests/oss-fuzz/fuzzer.h
@@ -0,0 +1,9 @@
+#ifndef FUZZER_H
+#define FUZZER_H 1
+
+#include <stdint.h>
+#include <stddef.h>
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size);
+
+#endif  /* fuzzer.h */
diff --git a/tests/oss-fuzz/json_parser_target.c b/tests/oss-fuzz/json_parser_target.c
new file mode 100644
index 000000000000..dc1d41b791fb
--- /dev/null
+++ b/tests/oss-fuzz/json_parser_target.c
@@ -0,0 +1,57 @@
+#include <config.h>
+#include "fuzzer.h"
+#include "jsonrpc.h"
+#include "openvswitch/json.h"
+#include "ovsdb-error.h"
+#include "ovsdb/table.h"
+#include <assert.h>
+#include <string.h>
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+    if ((size == 0) || (data[size-1] != '\0')) {
+        return 0;
+    }
+
+    struct json *j1, *j2;
+    struct jsonrpc_msg *msg;
+
+    // j1 alloc
+    j1 = json_from_string((const char *)data);
+    if (j1->type == JSON_STRING) {
+        json_destroy(j1);
+        return 0;
+        // j1 freed
+    }
+
+    // s1 alloc
+    char *s1 = json_to_string(j1, JSSF_SORT | JSSF_PRETTY);
+
+    // frees j1
+    char *error = jsonrpc_msg_from_json(j1, &msg);
+    if (error) {
+        free(s1);
+        free(error);
+        return 0;
+        // j1 freed by API call, s1 freed by hand
+    }
+
+    // j2 alloc, msg freed
+    j2 = jsonrpc_msg_to_json(msg);
+    if (j2->type == JSON_STRING) {
+        json_destroy(j2);
+        free(s1);
+        return 0;
+        // j2,s1 freed
+    }
+
+    // s2 alloc
+    char *s2 = json_to_string(j2, JSSF_SORT | JSSF_PRETTY);
+    json_destroy(j2);
+
+    free(s1);
+    free(s2);
+
+    return 0;
+    // j2,s1,s2 freed
+}
diff --git a/tests/oss-fuzz/ofp_print_target.c b/tests/oss-fuzz/ofp_print_target.c
new file mode 100644
index 000000000000..1b15214588e3
--- /dev/null
+++ b/tests/oss-fuzz/ofp_print_target.c
@@ -0,0 +1,50 @@
+#include <config.h>
+#include "fuzzer.h"
+#include "dp-packet.h"
+#include "openvswitch/ofp-print.h"
+#include "openvswitch/ofpbuf.h"
+#include "openvswitch/vlog.h"
+
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
+{
+    static bool isInit = false;
+    struct ofpbuf b;
+    if (size < sizeof(struct ofp_header)) {
+        return 0;
+    }
+
+    if (!isInit) {
+        vlog_set_verbosity("off");
+        isInit = true;
+    }
+
+    ofpbuf_use_const(&b, data, size);
+    for (;;) {
+        struct ofp_header *oh;
+        size_t length, tail_len;
+        void *tail;
+
+        // Check if ofpbuf contains ofp header
+        oh = (struct ofp_header *)ofpbuf_at(&b, 0, sizeof *oh);
+        if (!oh) {
+            break;
+        }
+
+        // Check if length is geq than lower bound
+        length = ntohs(oh->length);
+        if (length < sizeof *oh) {
+            break;
+        }
+
+        // Check if ofpbuf contains payload
+        tail_len = length - sizeof *oh;
+        tail = ofpbuf_at(&b, sizeof *oh, tail_len);
+        if (!tail) {
+            break;
+        }
+
+        ofp_print(stdout, ofpbuf_pull(&b, length), length, NULL, NULL, 2);
+    }
+    ofpbuf_uninit(&b);
+    return 0;
+}
-- 
2.16.1



More information about the dev mailing list