diff --git a/buildtools/wafsamba/samba_autoconf.py b/buildtools/wafsamba/samba_autoconf.py index 352b5ca31d3..ee15e34b5ec 100644 --- a/buildtools/wafsamba/samba_autoconf.py +++ b/buildtools/wafsamba/samba_autoconf.py @@ -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 diff --git a/buildtools/wafsamba/wscript b/buildtools/wafsamba/wscript index e5017a4a02f..ce5e0b48fc1 100644 --- a/buildtools/wafsamba/wscript +++ b/buildtools/wafsamba/wscript @@ -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 index 00000000000..3848838ba02 --- /dev/null +++ b/lib/fuzzing/README.md @@ -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 index 00000000000..f0d7fb4f46b --- /dev/null +++ b/lib/fuzzing/fuzzing.c @@ -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 . +*/ + +#include "includes.h" +#include "fuzzing/fuzzing.h" diff --git a/lib/fuzzing/fuzzing.h b/lib/fuzzing/fuzzing.h new file mode 100644 index 00000000000..67e49c3fbe0 --- /dev/null +++ b/lib/fuzzing/fuzzing.h @@ -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 . +*/ + +#ifndef _SAMBA_FUZZING_H +#define _SAMBA_FUZZING_H + +#include +#include + +/* 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 index 00000000000..f36bce5f409 --- /dev/null +++ b/lib/fuzzing/wscript_build @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +bld.SAMBA_SUBSYSTEM('fuzzing', + source='fuzzing.c', + deps='talloc', + enabled=bld.env.enable_libfuzzer, + ) diff --git a/wscript_build b/wscript_build index 771eb1fa0f7..ac6c044a605 100644 --- a/wscript_build +++ b/wscript_build @@ -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')