diff --git a/README.md b/README.md index 32999d292..d6261c190 100644 --- a/README.md +++ b/README.md @@ -133,9 +133,9 @@ Fuzzing There are several automated fuzzing tests in fwupd. These take some time to run: - CC=afl-gcc meson --default-library=static ../ - AFL_HARDEN=1 ninja - ninja fuzz-synaptics-rmi + CC=hfuzz-clang meson --default-library=static -Dtmpdir=/tmp -Dsystemd_root_prefix=/tmp ../ + ninja install ninja fuzz-firmware ninja fuzz-smbios ninja fuzz-efidbx + ninja fuzz-tpm-eventlog diff --git a/contrib/afl-fuzz.py b/contrib/afl-fuzz.py deleted file mode 100755 index 397e7f7d8..000000000 --- a/contrib/afl-fuzz.py +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/python3 -# SPDX-License-Identifier: LGPL-2.1+ - -import argparse -import sys -import subprocess -import os - - -def main(): - parser = argparse.ArgumentParser(description='Run afl-fuzz on all cores') - parser.add_argument('--input', '-i', help='fuzzing input directory') - parser.add_argument('--output', '-o', help='findings output directory') - parser.add_argument('--command', type=str, help='fuzzer tool command') - parser.add_argument('path', type=str, help='the fuzzer tool') - args = parser.parse_args() - if not args.input and not args.output: - print('-i and -o required') - return 1 - if not args.path: - print('tool name required') - return 1 - - # create if not already exists - if not os.path.exists(args.output): - os.makedirs(args.output) - - # run the main instance - envp = None - argv = [ - 'afl-fuzz', - '-m300', - '-i', - args.input, - '-o', - args.output, - '-M', - 'fuzzer00', - args.path, - ] - if args.command: - argv.append(args.command) - argv.append('@@') - print(argv) - p = subprocess.Popen(argv, env=envp) - - # run the secondary instances - cs = [] - for i in range(1, os.cpu_count()): - argv = [ - 'afl-fuzz', - '-m300', - '-i', - args.input, - '-o', - args.output, - '-S', - 'fuzzer%02i' % i, - args.path, - ] - if args.command: - argv.append(args.command) - argv.append('@@') - print(argv) - cs.append(subprocess.Popen(argv, env=envp, stdout=subprocess.DEVNULL)) - - # wait for the main instance - try: - p.wait() - except KeyboardInterrupt as _: - pass - for c in cs: - c.terminate() - return 0 - - -if __name__ == '__main__': - sys.exit(main()) diff --git a/meson.build b/meson.build index 4a0557112..e7c19e36a 100644 --- a/meson.build +++ b/meson.build @@ -73,7 +73,6 @@ warning_flags = [ '-Wformat-signedness', '-Wignored-qualifiers', '-Wimplicit-function-declaration', - '-Wincompatible-pointer-types-discards-qualifiers', '-Winit-self', '-Wlogical-op', '-Wmaybe-uninitialized', @@ -113,6 +112,12 @@ warning_flags = [ cc = meson.get_compiler('c') add_project_arguments(cc.get_supported_arguments(warning_flags), language : 'c') +# use honggfuzz for parallel persistent fuzzing +honggfuzz = find_program('honggfuzz', required: cc.has_function('HF_ITER')) +if honggfuzz.found() + conf.set('HAVE_HF_ITER', '1') +endif + if not meson.is_cross_build() add_project_arguments('-fstack-protector-strong', language : 'c') endif diff --git a/plugins/dfu/fuzzing.md b/plugins/dfu/fuzzing.md deleted file mode 100644 index 1b73ff68a..000000000 --- a/plugins/dfu/fuzzing.md +++ /dev/null @@ -1,6 +0,0 @@ -Fuzzing -======= - - CC=afl-gcc meson --default-library=static ../ - AFL_HARDEN=1 ninja - afl-fuzz -m 300 -i fuzzing -o findings ./plugins/dfu/dfu-tool --force dump @@ diff --git a/plugins/optionrom/fuzzing/meson.build b/plugins/optionrom/fuzzing/meson.build deleted file mode 100644 index 06c1cf426..000000000 --- a/plugins/optionrom/fuzzing/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -run_target('fuzz-optionrom', - command: [ - join_paths(meson.source_root(), 'contrib/afl-fuzz.py'), - '--command', 'rom', - '-i', meson.current_source_dir(), - '-o', join_paths(meson.current_build_dir(), '..', 'findings'), - optionrom_tool, - ], -) diff --git a/plugins/optionrom/meson.build b/plugins/optionrom/meson.build index 8d0674062..a05c308a6 100644 --- a/plugins/optionrom/meson.build +++ b/plugins/optionrom/meson.build @@ -79,5 +79,17 @@ if get_option('tests') install_dir : installed_test_bindir, ) test('optionrom-self-test', e, env : testdatadirs) # added to installed-tests - subdir('fuzzing') +endif + +if honggfuzz.found() + run_target('fuzz-optionrom', + command: [ + honggfuzz, + '--input', join_paths(meson.current_source_dir(), 'fuzzing'), + '--output', join_paths(meson.current_build_dir(), 'fuzzing-corpus'), + '--workspace', join_paths(meson.current_build_dir(), 'fuzzing-findings'), + '--verifier', + '--', optionrom_tool, 'rom', '___FILE___', + ], + ) endif diff --git a/plugins/synaptics-rmi/fuzzing/meson.build b/plugins/synaptics-rmi/fuzzing/meson.build deleted file mode 100644 index 0ee9d9514..000000000 --- a/plugins/synaptics-rmi/fuzzing/meson.build +++ /dev/null @@ -1,20 +0,0 @@ -synaptics_example0x = custom_target('example0x.img', - output: 'example0x.img', - command: [synaptics_rmi_dump, 'gen0x', '@OUTPUT@'], -) -synaptics_example10 = custom_target('example10.img', - output: 'example10.img', - command: [synaptics_rmi_dump, 'gen10', '@OUTPUT@'], -) -run_target('fuzz-synaptics-rmi', - command: [ - join_paths(meson.source_root(), 'contrib/afl-fuzz.py'), - '-i', meson.current_build_dir(), - '-o', join_paths(meson.current_build_dir(), '..', 'findings'), - synaptics_rmi_dump, - ], - depends: [ - synaptics_example0x, - synaptics_example10, - ], -) diff --git a/plugins/synaptics-rmi/meson.build b/plugins/synaptics-rmi/meson.build index 3272fad87..5d9f65511 100644 --- a/plugins/synaptics-rmi/meson.build +++ b/plugins/synaptics-rmi/meson.build @@ -56,5 +56,4 @@ if get_option('tests') ], c_args : cargs ) - subdir('fuzzing') endif diff --git a/plugins/tpm-eventlog/fuzzing/v2.bin b/plugins/tpm-eventlog/fuzzing/v2.bin new file mode 100644 index 000000000..9d1e77a85 --- /dev/null +++ b/plugins/tpm-eventlog/fuzzing/v2.bin @@ -0,0 +1 @@ +Spec ID Event03 diff --git a/plugins/tpm-eventlog/meson.build b/plugins/tpm-eventlog/meson.build index 3f7e7aa76..0ee894fb3 100644 --- a/plugins/tpm-eventlog/meson.build +++ b/plugins/tpm-eventlog/meson.build @@ -98,11 +98,15 @@ if get_option('man') ) endif -run_target('fuzz-tpm-eventlog', - command: [ - join_paths(meson.source_root(), 'contrib/afl-fuzz.py'), - '-i', join_paths(meson.current_source_dir(), 'tests'), - '-o', join_paths(meson.current_build_dir(), 'findings'), - fwupdtpmevlog, - ], -) +if honggfuzz.found() + run_target('fuzz-tpm-eventlog', + command: [ + honggfuzz, + '--input', join_paths(meson.current_source_dir(), 'fuzzing'), + '--output', join_paths(meson.current_build_dir(), 'fuzzing-corpus'), + '--workspace', join_paths(meson.current_build_dir(), 'fuzzing-findings'), + '--verifier', + '--', fwupdtpmevlog, '___FILE___', + ], + ) +endif diff --git a/plugins/uefi-dbx/meson.build b/plugins/uefi-dbx/meson.build index 1ffe20de0..ef388a03e 100644 --- a/plugins/uefi-dbx/meson.build +++ b/plugins/uefi-dbx/meson.build @@ -137,12 +137,15 @@ if get_option('man') ) endif -run_target('fuzz-efidbx', - command: [ - join_paths(meson.source_root(), 'contrib/afl-fuzz.py'), - '-i', join_paths(meson.current_source_dir(), 'fuzzing'), - '-o', join_paths(meson.current_build_dir(), 'findings'), - '--command', uefi_dbx_fuzzer, - fwupdtool, - ], -) +if honggfuzz.found() + run_target('fuzz-efidbx', + command: [ + honggfuzz, + '--input', join_paths(meson.current_source_dir(), 'fuzzing'), + '--output', join_paths(meson.current_build_dir(), 'fuzzing-corpus'), + '--workspace', join_paths(meson.current_build_dir(), 'fuzzing-findings'), + '--verifier', + '--', uefi_dbx_fuzzer, '___FILE___', + ], + ) +endif diff --git a/src/fu-firmware-dump.c b/src/fu-firmware-dump.c index eaa90c0bf..89b57f4b8 100644 --- a/src/fu-firmware-dump.c +++ b/src/fu-firmware-dump.c @@ -1,58 +1,236 @@ /* - * Copyright (C) 2019 Richard Hughes + * Copyright (C) 2019-2020 Richard Hughes * * SPDX-License-Identifier: LGPL-2.1+ */ #include "config.h" -#include "fu-common.h" -#include "fu-srec-firmware.h" -#include "fu-ihex-firmware.h" +#include +#include +#include + +#include "fu-engine.h" + +typedef struct { + gboolean verbose; + gint timeout; /* ms */ + GPtrArray *array; /* element-type FuFirmware */ + FuEngine *engine; +} FuUtil; + +extern void HF_ITER(guint8 **buf, gsize *len); + +static gboolean +fu_firmware_dump_parse (FuUtil *self, + FuFirmware *firmware, + GBytes *fw, + GError **error) +{ + gboolean ret; + gdouble elapsed_ms; + g_autoptr(GError) error_local = NULL; + g_autoptr(GTimer) timer = g_timer_new (); + + /* parse, relaxing all the restrictions */ + ret = fu_firmware_parse (firmware, fw, + FWUPD_INSTALL_FLAG_NO_SEARCH | + FWUPD_INSTALL_FLAG_IGNORE_VID_PID | + FWUPD_INSTALL_FLAG_IGNORE_CHECKSUM, + &error_local); + + /* a timeout is more important than the actual parse failure */ + elapsed_ms = g_timer_elapsed (timer, NULL) * 1000; + if (self->timeout > 0 && + elapsed_ms > self->timeout) { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_TIMED_OUT, + "%s took %.1fms (more than limit of %ims)", + G_OBJECT_TYPE_NAME (firmware), + elapsed_ms, + self->timeout); + return FALSE; + } + + /* success? */ + if (!ret) { + g_propagate_prefixed_error (error, + g_steal_pointer (&error_local), + "%s failed in %.0lfms: ", + G_OBJECT_TYPE_NAME (firmware), + elapsed_ms); + return FALSE; + } + return TRUE; +} + +static gboolean +fu_firmware_dump_iter (FuUtil *self, GBytes *blob, GError **error) +{ + gboolean any_okay = FALSE; + for (guint i = 0; i < self->array->len; i++) { + FuFirmware *firmware = g_ptr_array_index (self->array, i); + g_autoptr(GError) error_local = NULL; + g_autofree gchar *str = NULL; + + if (!fu_firmware_dump_parse (self, firmware, blob, &error_local)) { + /* timeout so bail */ + if (g_error_matches (error_local, + G_IO_ERROR, + G_IO_ERROR_TIMED_OUT)) { + g_propagate_error (error, g_steal_pointer (&error_local)); + return FALSE; + } + g_printerr ("%s\n", error_local->message); + continue; + } + str = fu_firmware_to_string (firmware); + g_print ("%s", str); + any_okay = TRUE; + } + if (!any_okay) { + g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to parse"); + return FALSE; + } + return TRUE; +} + +static void +fu_firmware_dump_log_cb (const gchar *log_domain, + GLogLevelFlags log_level, + const gchar *message, + gpointer user_data) +{ + FuUtil *self = (FuUtil *) user_data; + if (log_level == G_LOG_LEVEL_CRITICAL) { + g_printerr ("CRITICAL: %s\n", message); + g_assert_not_reached (); + } + if (self->verbose) + g_printerr ("DEBUG: %s\n", message); +} + +static void +fu_util_private_free (FuUtil *self) +{ + if (self->array != NULL) + g_ptr_array_unref (self->array); + if (self->engine != NULL) + g_object_unref (self->engine); + g_free (self); +} + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-function" +G_DEFINE_AUTOPTR_CLEANUP_FUNC(FuUtil, fu_util_private_free) +#pragma clang diagnostic pop int main (int argc, char **argv) { - g_autofree gchar *str = NULL; - g_autoptr(FuFirmware) firmware = NULL; - g_autoptr(GBytes) blob = NULL; g_autoptr(GError) error = NULL; - gsize sz = 0; - const guint8 *buf; + g_autoptr(GPtrArray) firmware_types = NULL; + g_autoptr(GOptionContext) context = NULL; + g_autoptr(FuUtil) self = g_new0 (FuUtil, 1); + const GOptionEntry options[] = { + { "verbose", 'v', 0, G_OPTION_ARG_NONE, &self->verbose, + /* TRANSLATORS: command line option */ + _("Show extra debugging information"), NULL }, + { "timeout", 't', 0, G_OPTION_ARG_INT, &self->timeout, + /* TRANSLATORS: command line option */ + _("Timeout in milliseconds for each parse"), NULL }, + { NULL} + }; - /* no args */ - if (argc != 2) { - g_printerr ("firmware filename required\n"); - return 2; + setlocale (LC_ALL, ""); + + bindtextdomain (GETTEXT_PACKAGE, FWUPD_LOCALEDIR); + bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); + textdomain (GETTEXT_PACKAGE); + + context = g_option_context_new (NULL); + g_option_context_add_main_entries (context, options, NULL); + if (!g_option_context_parse (context, &argc, &argv, &error)) { + /* TRANSLATORS: the user didn't read the man page */ + g_printerr ("%s: %s\n", _("Failed to parse arguments"), + error->message); + return EXIT_FAILURE; } - /* load firmware */ - blob = fu_common_get_contents_bytes (argv[1], &error); - if (blob == NULL) { - g_printerr ("failed to load file: %s\n", error->message); + /* args */ + if (self->verbose) { + g_setenv ("G_MESSAGES_DEBUG", "all", FALSE); + g_setenv ("FWUPD_VERBOSE", "1", FALSE); + } + + /* crashy mccrash face */ + g_log_set_default_handler (fu_firmware_dump_log_cb, self); + + /* load engine */ + self->engine = fu_engine_new (FU_APP_FLAGS_NO_IDLE_SOURCES); + if (!fu_engine_load (self->engine, FU_ENGINE_LOAD_FLAG_READONLY, &error)) { + g_printerr ("Failed to load engine: %s\n", error->message); return 1; } - buf = g_bytes_get_data (blob, &sz); - if (sz < 2) { - g_printerr ("firmware invalid\n"); - return 2; + + /* get all parser objects */ + firmware_types = fu_engine_get_firmware_gtype_ids (self->engine); + self->array = g_ptr_array_new_with_free_func ((GDestroyNotify) g_object_unref); + for (guint i = 0; i < firmware_types->len; i++) { + const gchar *id = g_ptr_array_index (firmware_types, i); + GType gtype = fu_engine_get_firmware_gtype_by_id (self->engine, id); + g_ptr_array_add (self->array, g_object_new (gtype, NULL)); } - if (buf[0] == 'S' && buf[1] == '0') { - firmware = fu_srec_firmware_new (); - } else if (buf[0] == ':') { - firmware = fu_ihex_firmware_new (); - } else { - g_printerr ("firmware invalid type, expected .srec or .hex\n"); - return 2; + + /* no args */ + if (argc >= 2) { + gint rc = 0; + for (gint i = 1; i < argc; i++) { + g_autoptr(GBytes) blob = NULL; + g_autoptr(GError) error_local = NULL; + blob = fu_common_get_contents_bytes (argv[i], &error_local); + if (blob == NULL) { + g_printerr ("failed to load file %s: %s\n", + argv[i], error_local->message); + rc = 2; + continue; + } + if (!fu_firmware_dump_iter (self, blob, &error_local)) { + g_printerr ("failed to parse file %s: %s\n", + argv[i], error_local->message); + if (g_error_matches (error_local, + G_IO_ERROR, + G_IO_ERROR_TIMED_OUT)) { + return 4; + } + rc = 3; + continue; + } + } + return rc; } - if (!fu_firmware_parse (firmware, blob, - FWUPD_INSTALL_FLAG_IGNORE_VID_PID | - FWUPD_INSTALL_FLAG_IGNORE_CHECKSUM, - &error)) { - g_printerr ("failed to parse file: %s\n", error->message); - return 3; + for (;;) { + gsize len = 0; + guint8 *buf = NULL; + g_autoptr(GBytes) blob = NULL; +#ifdef HAVE_HF_ITER + HF_ITER(&buf, &len); +#endif + blob = g_bytes_new_static (buf, len); + for (guint i = 0; i < self->array->len; i++) { + FuFirmware *firmware = g_ptr_array_index (self->array, i); + g_autoptr(GError) error_local = NULL; + if (!fu_firmware_dump_parse (self, firmware, blob, &error_local)) { + if (g_error_matches (error_local, + G_IO_ERROR, + G_IO_ERROR_TIMED_OUT)) { + g_error ("%s", error_local->message); + } + g_assert (error_local != NULL); + continue; + } + } } - str = fu_firmware_to_string (firmware); - g_print ("%s", str); return 0; } diff --git a/src/fuzzing/bcm57xx-stage1.bin b/src/fuzzing/bcm57xx-stage1.bin new file mode 100644 index 000000000..4ae08e6d0 Binary files /dev/null and b/src/fuzzing/bcm57xx-stage1.bin differ diff --git a/src/fuzzing/bcm57xx.builder.xml b/src/fuzzing/bcm57xx.builder.xml new file mode 100644 index 000000000..ce7d36e04 --- /dev/null +++ b/src/fuzzing/bcm57xx.builder.xml @@ -0,0 +1,18 @@ + + 1.2.3 + + 7.8.9 + stage1 + 0x01 + bcm57xx-stage1.bin + + + stage2 + + + + ape + 0x7 + aGVsbG8gd29ybGQ= + + diff --git a/src/fuzzing/cros-ec.builder.xml b/src/fuzzing/cros-ec.builder.xml new file mode 100644 index 000000000..2072504d4 --- /dev/null +++ b/src/fuzzing/cros-ec.builder.xml @@ -0,0 +1,19 @@ + + 0x3000 + + RO_FRID + Y2hlZXNlX3YxLjEuMTc1NS00ZGE5NTIwICAgICAgICA= + + + RW_FWID + Y2hlZXNlX3YxLjEuMTc1NS00ZGE5NTIwICAgICAgICA= + + + EC_RO + Y2hlZXNlX3YxLjEuMTc1NS00ZGE5NTIwICAgICAgICA= + + + EC_RW + Y2hlZXNlX3YxLjEuMTc1NS00ZGE5NTIwICAgICAgICA= + + diff --git a/src/fuzzing/firmware/bcm57xx.bin b/src/fuzzing/firmware/bcm57xx.bin new file mode 100644 index 000000000..158430b40 Binary files /dev/null and b/src/fuzzing/firmware/bcm57xx.bin differ diff --git a/src/fuzzing/firmware/cros-ec.bin b/src/fuzzing/firmware/cros-ec.bin new file mode 100644 index 000000000..004cad7ee Binary files /dev/null and b/src/fuzzing/firmware/cros-ec.bin differ diff --git a/plugins/dfu/fuzzing/metadata-multiple.dfu b/src/fuzzing/firmware/dfu-metadata-multiple.dfu similarity index 100% rename from plugins/dfu/fuzzing/metadata-multiple.dfu rename to src/fuzzing/firmware/dfu-metadata-multiple.dfu diff --git a/plugins/dfu/fuzzing/metadata.dfu b/src/fuzzing/firmware/dfu-metadata.dfu similarity index 100% rename from plugins/dfu/fuzzing/metadata.dfu rename to src/fuzzing/firmware/dfu-metadata.dfu diff --git a/plugins/dfu/fuzzing/example.dfu b/src/fuzzing/firmware/dfu.dfu similarity index 100% rename from plugins/dfu/fuzzing/example.dfu rename to src/fuzzing/firmware/dfu.dfu diff --git a/plugins/dfu/fuzzing/example.dfuse b/src/fuzzing/firmware/dfu.dfuse similarity index 100% rename from plugins/dfu/fuzzing/example.dfuse rename to src/fuzzing/firmware/dfu.dfuse diff --git a/src/fuzzing/firmware/ebitdo.dat b/src/fuzzing/firmware/ebitdo.dat new file mode 100644 index 000000000..e01738cbd Binary files /dev/null and b/src/fuzzing/firmware/ebitdo.dat differ diff --git a/src/fuzzing/firmware/fmap.bin b/src/fuzzing/firmware/fmap.bin new file mode 100644 index 000000000..59850925d Binary files /dev/null and b/src/fuzzing/firmware/fmap.bin differ diff --git a/src/fuzzing/firmware/firmware.hex b/src/fuzzing/firmware/ihex.hex similarity index 100% rename from src/fuzzing/firmware/firmware.hex rename to src/fuzzing/firmware/ihex.hex diff --git a/src/fuzzing/firmware/rmi-0x.img b/src/fuzzing/firmware/rmi-0x.img new file mode 100644 index 000000000..808d8ca41 Binary files /dev/null and b/src/fuzzing/firmware/rmi-0x.img differ diff --git a/src/fuzzing/firmware/rmi-10.img b/src/fuzzing/firmware/rmi-10.img new file mode 100644 index 000000000..4043fed69 Binary files /dev/null and b/src/fuzzing/firmware/rmi-10.img differ diff --git a/src/fuzzing/firmware/solokey.json b/src/fuzzing/firmware/solokey.json new file mode 100644 index 000000000..60c2a88c6 --- /dev/null +++ b/src/fuzzing/firmware/solokey.json @@ -0,0 +1 @@ +{"firmware": "OjA0NDAwMDAwM0RFRjIwRjA4MAo6MDAwMDAwMDFGRgo=", "signature": "aGVsbG8gd29ybGQ="} diff --git a/src/fuzzing/firmware/example-addr32.srec b/src/fuzzing/firmware/srec-addr32.srec similarity index 100% rename from src/fuzzing/firmware/example-addr32.srec rename to src/fuzzing/firmware/srec-addr32.srec diff --git a/src/fuzzing/firmware/example.srec b/src/fuzzing/firmware/srec.srec similarity index 100% rename from src/fuzzing/firmware/example.srec rename to src/fuzzing/firmware/srec.srec diff --git a/src/fuzzing/firmware/synaprom.bin b/src/fuzzing/firmware/synaprom.bin new file mode 100644 index 000000000..43ad19ebc Binary files /dev/null and b/src/fuzzing/firmware/synaprom.bin differ diff --git a/src/fuzzing/firmware/wacom.wac b/src/fuzzing/firmware/wacom.wac new file mode 100644 index 000000000..465c093ca --- /dev/null +++ b/src/fuzzing/firmware/wacom.wac @@ -0,0 +1,9 @@ +WACOM2080080000009414E080400000009414A3F +WA10800800067 +S00B00004F616B2E73726563FE +S70508038BD58F + +WA2080400001F +S00B00004F616B2E73726563FE +S70508070BD50B + diff --git a/src/fuzzing/fmap.builder.xml b/src/fuzzing/fmap.builder.xml new file mode 100644 index 000000000..5e3c4bb5b --- /dev/null +++ b/src/fuzzing/fmap.builder.xml @@ -0,0 +1,10 @@ + + + FMAP + aGVsbG8gd29ybGQ= + + + TEST + V29ybGQh + + diff --git a/src/fuzzing/meson.build b/src/fuzzing/meson.build index a6d13c4b2..d8ae9a9ef 100644 --- a/src/fuzzing/meson.build +++ b/src/fuzzing/meson.build @@ -1,17 +1,25 @@ -run_target('fuzz-smbios', - command: [ - join_paths(meson.source_root(), 'contrib/afl-fuzz.py'), - '-i', join_paths(meson.current_source_dir(), 'smbios'), - '-o', join_paths(meson.current_build_dir(), '..', 'findings-smbios'), - '--command', 'smbios-dump', - fwupdtool, - ], -) -run_target('fuzz-firmware', - command: [ - join_paths(meson.source_root(), 'contrib/afl-fuzz.py'), - '-i', join_paths(meson.current_source_dir(), 'firmware'), - '-o', join_paths(meson.current_build_dir(), '..', 'findings-firmware'), - fwupd_firmware_dump, - ], +if honggfuzz.found() + run_target('fuzz-smbios', + command: [ + honggfuzz, + '--input', join_paths(meson.current_source_dir(), 'smbios'), + '--output', join_paths(meson.current_build_dir(), 'smbios-corpus'), + '--workspace', join_paths(meson.current_build_dir(), 'smbios-findings'), + '--verifier', + '--rlimit_rss', '10', + '--', fwupdtool, 'smbios-dump', '___FILE___', + ], + ) + run_target('fuzz-firmware', + command: [ + honggfuzz, + '--input', join_paths(meson.current_source_dir(), 'firmware'), + '--output', join_paths(meson.current_build_dir(), 'firmware-corpus'), + '--workspace', join_paths(meson.current_build_dir(), 'firmware-findings'), + '--verifier', + '--rlimit_rss', '10', + '--timeout', '5', '-P', '--', + fwupd_firmware_dump, '--timeout', '50', + ], ) +endif diff --git a/src/fuzzing/synaprom.builder.xml b/src/fuzzing/synaprom.builder.xml new file mode 100644 index 000000000..1caaebd6b --- /dev/null +++ b/src/fuzzing/synaprom.builder.xml @@ -0,0 +1,7 @@ + + 1.2 + + 0x42 + aGVsbG8gd29ybGQ= + + diff --git a/src/meson.build b/src/meson.build index cfdceac89..65488ba66 100644 --- a/src/meson.build +++ b/src/meson.build @@ -307,14 +307,13 @@ if get_option('tests') ], ) test('fu-self-test', e, is_parallel:false, timeout:180) -endif -if get_option('tests') # for fuzzing fwupd_firmware_dump = executable( 'fwupd-firmware-dump', sources : [ 'fu-firmware-dump.c', + daemon_src, ], include_directories : [ root_incdir, @@ -322,8 +321,7 @@ if get_option('tests') fwupdplugin_incdir, ], dependencies : [ - libxmlb, - gio, + daemon_dep, ], link_with : [ fwupd, @@ -332,6 +330,4 @@ if get_option('tests') ) endif -if get_option('tests') - subdir('fuzzing') -endif +subdir('fuzzing')