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

Bhargava Shastry bshastry at sect.tu-berlin.de
Tue Jul 10 09:10:17 UTC 2018


Hi Ben,

Thanks a lot for the new patch. A couple of comments:

- Could you please rename each of `tests/oss-fuzz/config/*.options` from
*_fuzzer.options to *_target.options. This is because oss-fuzz infra
requires namesake fuzzer binaries and option.

Example: flow_extract_fuzzer.options renamed to
flow_extract_target.options etc.

- Could you please add "tests/oss-fuzz/fuzzer.h" to the distribution. At
the moment, I get the following build error:

```
The following files are in git but not the distribution:
tests/oss-fuzz/fuzzer.h
Makefile:6314: recipe for target 'dist-hook-git' failed
make[2]: *** [dist-hook-git] Error 1
make[2]: Leaving directory '/src/openvswitch'
Makefile:5755: recipe for target 'all-recursive' failed
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory '/src/openvswitch'
Makefile:3373: recipe for target 'all' failed
make: *** [all] Error 2
```

Thanks a lot,
Bhargava

On 07/09/2018 11:18 PM, Ben Pfaff wrote:
> 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;
> +}
> 

-- 
Bhargava Shastry <bshastry at sect.tu-berlin.de>
Security in Telecommunications
TU Berlin / Telekom Innovation Laboratories
Ernst-Reuter-Platz 7, Sekr TEL 17 / D - 10587 Berlin, Germany
phone: +49 30 8353 58235
Keybase: https://keybase.io/bshastry


More information about the dev mailing list