Add fuzzing support to build system
authorMichael Hanselmann <public@hansmi.ch>
Wed, 3 Apr 2019 22:23:07 +0000 (00:23 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 7 Aug 2019 06:07:28 +0000 (06:07 +0000)
LibFuzzer, Honggfuzz and other programs implement simple interfaces for
fuzzing appropriately prepared code. Samba contains quite a lot of
parsing code, often a good target for fuzzing.

With this change the build system is amended to support building fuzzing
binaries (added in later changes).

Signed-off-by: Michael Hanselmann <public@hansmi.ch>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
buildtools/wafsamba/samba_autoconf.py
buildtools/wafsamba/wscript
lib/fuzzing/README.md [new file with mode: 0644]
lib/fuzzing/fuzzing.c [new file with mode: 0644]
lib/fuzzing/fuzzing.h [new file with mode: 0644]
lib/fuzzing/wscript_build [new file with mode: 0644]
wscript_build

index 352b5ca31d3883aadbe1bd37e401452d29bb52af..ee15e34b5ec7476094894fc9fe29c82fd9a934ca 100644 (file)
@@ -938,6 +938,11 @@ def SETUP_CONFIGURE_CACHE(conf, enable):
 
 @conf
 def SAMBA_CHECK_UNDEFINED_SYMBOL_FLAGS(conf):
+    if Options.options.address_sanitizer or Options.options.enable_libfuzzer:
+        # Sanitizers can rely on symbols undefined at library link time and the
+        # symbols used for fuzzers are only defined by compiler wrappers.
+        return
+
     if not sys.platform.startswith("openbsd"):
         # we don't want any libraries or modules to rely on runtime
         # resolution of symbols
index e5017a4a02f367eaafb793d94c77e81206765c0f..ce5e0b48fc1060ae18493b5b25d219b37dfdcf78 100644 (file)
@@ -129,6 +129,9 @@ def options(opt):
         action="store_true",
         dest='undefined_sanitizer',
         default=False)
+    gr.add_option('--enable-libfuzzer',
+                  help=("Build fuzzing binaries (requires compiler options for libFuzzer or compiler wrapper such as honggfuzz/hfuzz-cc)"),
+                  action="store_true", dest='enable_libfuzzer', default=False)
 
     gr.add_option('--abi-check',
                   help=("Check ABI signatures for libraries"),
@@ -590,6 +593,10 @@ struct foo bar = { .y = 'X', .x = 1 };
                     eprintf("bla", "bar")
                     ''', define='HAVE__VA_ARGS__MACRO')
 
+    conf.env.enable_libfuzzer = Options.options.enable_libfuzzer
+    if conf.env.enable_libfuzzer:
+        conf.DEFINE('ENABLE_LIBFUZZER', 1)
+
     conf.SAMBA_BUILD_ENV()
 
 
diff --git a/lib/fuzzing/README.md b/lib/fuzzing/README.md
new file mode 100644 (file)
index 0000000..3848838
--- /dev/null
@@ -0,0 +1,35 @@
+# Fuzzing Samba
+
+Fuzzing supplies valid, invalid, unexpected or random data as input to a piece
+of code. Instrumentation, usually compiler-implemented, is used to monitor for
+exceptions such as crashes, assertions or memory corruption.
+
+See [Wikipedia article on fuzzing](https://en.wikipedia.org/wiki/Fuzzing) for
+more information.
+
+
+## Configure with fuzzing
+
+Example command line to build binaries for use with
+[honggfuzz](https://github.com/google/honggfuzz/):
+
+```sh
+buildtools/bin/waf -C --without-gettext --enable-debug --enable-developer \
+       --address-sanitizer --enable-libfuzzer \
+       CC=.../honggfuzz/hfuzz_cc/hfuzz-clang configure \
+       LINK_CC=.../honggfuzz/hfuzz_cc/hfuzz-clang
+```
+
+
+## Fuzzing tiniparser
+
+Example for fuzzing `tiniparser` using `honggfuzz` (see `--help` for more
+options):
+
+```sh
+buildtools/bin/waf --targets=fuzz_tiniparser build && \
+.../honggfuzz/honggfuzz --sanitizers --timeout 3 --max_file_size 256 \
+  --rlimit_rss 100 -f .../tiniparser-corpus -- bin/fuzz_tiniparser
+```
+
+# vim: set sw=8 sts=8 ts=8 tw=79 :
diff --git a/lib/fuzzing/fuzzing.c b/lib/fuzzing/fuzzing.c
new file mode 100644 (file)
index 0000000..f0d7fb4
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+   Unix SMB/CIFS implementation.
+   Fuzzing utility functions
+   Copyright (C) Michael Hanselmann 2019
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "fuzzing/fuzzing.h"
diff --git a/lib/fuzzing/fuzzing.h b/lib/fuzzing/fuzzing.h
new file mode 100644 (file)
index 0000000..67e49c3
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+   Unix SMB/CIFS implementation.
+   Fuzzing utility functions
+   Copyright (C) Michael Hanselmann 2019
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _SAMBA_FUZZING_H
+#define _SAMBA_FUZZING_H
+
+#include <stddef.h>
+#include <stdint.h>
+
+/* Prototypes for fuzzing interface */
+int LLVMFuzzerInitialize(int *argc, char ***argv);
+int LLVMFuzzerTestOneInput(uint8_t * buf, size_t len);
+
+#endif /* _SAMBA_FUZZING_H */
diff --git a/lib/fuzzing/wscript_build b/lib/fuzzing/wscript_build
new file mode 100644 (file)
index 0000000..f36bce5
--- /dev/null
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+bld.SAMBA_SUBSYSTEM('fuzzing',
+    source='fuzzing.c',
+    deps='talloc',
+    enabled=bld.env.enable_libfuzzer,
+    )
index 771eb1fa0f715e3414748fab8c3ab4aee718bd0e..ac6c044a605b90cc762dca466ef4d6dfff1303a3 100644 (file)
@@ -150,6 +150,7 @@ bld.RECURSE('dfs_server')
 bld.RECURSE('file_server')
 bld.RECURSE('lib/krb5_wrap')
 bld.RECURSE('packaging')
+bld.RECURSE('lib/fuzzing')
 
 bld.RECURSE('testsuite/headers')