diff options
author | Patrick Griffis <pgriffis@igalia.com> | 2020-12-15 17:42:40 -0600 |
---|---|---|
committer | Patrick Griffis <pgriffis@igalia.com> | 2020-12-16 13:36:06 -0600 |
commit | 46969e196a1b29120c5ae1fefa83df0152274e7b (patch) | |
tree | d885b0aaa5272225cba88727c194c76c0c803a5f /fuzzing | |
parent | 9eb8f2faa5b8657804175ef5a50cffbc3c602754 (diff) | |
download | libsoup-46969e196a1b29120c5ae1fefa83df0152274e7b.tar.gz |
Add basic fuzzing support
Diffstat (limited to 'fuzzing')
-rw-r--r-- | fuzzing/fuzz.h | 21 | ||||
-rw-r--r-- | fuzzing/fuzz_cookie_parse.c | 17 | ||||
-rw-r--r-- | fuzzing/fuzz_cookie_parse.dict | 9 | ||||
-rw-r--r-- | fuzzing/fuzz_decode_data_uri.c | 19 | ||||
-rw-r--r-- | fuzzing/fuzz_decode_data_uri.dict | 5 | ||||
-rw-r--r-- | fuzzing/meson.build | 46 |
6 files changed, 117 insertions, 0 deletions
diff --git a/fuzzing/fuzz.h b/fuzzing/fuzz.h new file mode 100644 index 00000000..0d380285 --- /dev/null +++ b/fuzzing/fuzz.h @@ -0,0 +1,21 @@ +#include "libsoup/soup.h" + +int LLVMFuzzerTestOneInput (const unsigned char *data, size_t size); + +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +static GLogWriterOutput +empty_logging_func (GLogLevelFlags log_level, const GLogField *fields, + gsize n_fields, gpointer user_data) +{ + return G_LOG_WRITER_HANDLED; +} +#endif + +/* Disables logging for oss-fuzz. Must be used with each target. */ +static void +fuzz_set_logging_func (void) +{ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + g_log_set_writer_func (empty_logging_func, NULL, NULL); +#endif +} diff --git a/fuzzing/fuzz_cookie_parse.c b/fuzzing/fuzz_cookie_parse.c new file mode 100644 index 00000000..296b8d75 --- /dev/null +++ b/fuzzing/fuzz_cookie_parse.c @@ -0,0 +1,17 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + // We only accept NUL terminated strings + if (!size || data[size - 1] != '\0') + return 0; + + fuzz_set_logging_func (); + + SoupCookie *cookie = soup_cookie_parse ((char*)data, NULL); + + g_clear_pointer (&cookie, soup_cookie_free); + + return 0; +}
\ No newline at end of file diff --git a/fuzzing/fuzz_cookie_parse.dict b/fuzzing/fuzz_cookie_parse.dict new file mode 100644 index 00000000..bed45447 --- /dev/null +++ b/fuzzing/fuzz_cookie_parse.dict @@ -0,0 +1,9 @@ +"domain=" +"expires=" +"httponly" +"max-age=" +"secure" +"samesite=" +"path=" +"=" +";"
\ No newline at end of file diff --git a/fuzzing/fuzz_decode_data_uri.c b/fuzzing/fuzz_decode_data_uri.c new file mode 100644 index 00000000..97e0369f --- /dev/null +++ b/fuzzing/fuzz_decode_data_uri.c @@ -0,0 +1,19 @@ +#include "fuzz.h" + +int +LLVMFuzzerTestOneInput (const unsigned char *data, size_t size) +{ + GBytes *bytes; + char *data_uri; + + fuzz_set_logging_func (); + + data_uri = g_strdup_printf ("data:%.*s", (int)size, data); + // g_print("%s", data_uri); + bytes = soup_uri_decode_data_uri (data_uri, NULL); + + g_clear_pointer (&bytes, g_bytes_unref); + g_free (data_uri); + + return 0; +}
\ No newline at end of file diff --git a/fuzzing/fuzz_decode_data_uri.dict b/fuzzing/fuzz_decode_data_uri.dict new file mode 100644 index 00000000..25fff80b --- /dev/null +++ b/fuzzing/fuzz_decode_data_uri.dict @@ -0,0 +1,5 @@ +";base64," +"," +";" +"text/plain" +"text/plain;base64,"
\ No newline at end of file diff --git a/fuzzing/meson.build b/fuzzing/meson.build new file mode 100644 index 00000000..865bfcd3 --- /dev/null +++ b/fuzzing/meson.build @@ -0,0 +1,46 @@ +fs = import('fs') + +fuzz_targets = [ + 'fuzz_decode_data_uri', + 'fuzz_cookie_parse', +] + +fuzzing_args = '-fsanitize=fuzzer,address,undefined' +have_fuzzing = cc.has_argument(fuzzing_args) +fuzzing_feature = get_option('fuzzing') + +if not have_fuzzing and fuzzing_feature.enabled() + error('clang and libfuzzer are required for fuzzing') +endif + +if have_fuzzing and (fuzzing_feature.enabled() or fuzzing_feature.auto()) + foreach target : fuzz_targets + exe = executable(target, [target + '.c'], + c_args : [fuzzing_args, '-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION'], + link_args : fuzzing_args, + dependencies : libsoup_dep, + ) + + extra_args = [] + dict_file = join_paths(meson.current_source_dir(), target + '.dict') + if fs.exists(dict_file) + extra_args += '-dict=' + dict_file + endif + + test(target, exe, + args: [ + '-runs=500000', + '-jobs=16', # This will automatically limit itself to half your systems threads + '-artifact_prefix=meson-logs/' + target + '-', + '-print_final_stats=1', + ] + extra_args, + env: [ + 'ASAN_OPTIONS=fast_unwind_on_malloc=0', + 'UBSAN_OPTIONS=print_stacktrace=1', + ], + suite: 'fuzzing', + timeout: 240, + priority: -1, + ) + endforeach +endif
\ No newline at end of file |