mirror of
https://git.proxmox.com/git/fwupd
synced 2025-08-14 10:44:12 +00:00
Use honggfuzz to fuzz firmware rather than AFL
This has better multi-core performance and can run in persistent mode -- which allows us to construct a test harness of all the parsers (which takes time) and then just reuse the process for lots of different data.
This commit is contained in:
parent
531b8b417f
commit
c4ca8e25d1
@ -133,9 +133,9 @@ Fuzzing
|
|||||||
|
|
||||||
There are several automated fuzzing tests in fwupd. These take some time to run:
|
There are several automated fuzzing tests in fwupd. These take some time to run:
|
||||||
|
|
||||||
CC=afl-gcc meson --default-library=static ../
|
CC=hfuzz-clang meson --default-library=static -Dtmpdir=/tmp -Dsystemd_root_prefix=/tmp ../
|
||||||
AFL_HARDEN=1 ninja
|
ninja install
|
||||||
ninja fuzz-synaptics-rmi
|
|
||||||
ninja fuzz-firmware
|
ninja fuzz-firmware
|
||||||
ninja fuzz-smbios
|
ninja fuzz-smbios
|
||||||
ninja fuzz-efidbx
|
ninja fuzz-efidbx
|
||||||
|
ninja fuzz-tpm-eventlog
|
||||||
|
@ -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())
|
|
@ -73,7 +73,6 @@ warning_flags = [
|
|||||||
'-Wformat-signedness',
|
'-Wformat-signedness',
|
||||||
'-Wignored-qualifiers',
|
'-Wignored-qualifiers',
|
||||||
'-Wimplicit-function-declaration',
|
'-Wimplicit-function-declaration',
|
||||||
'-Wincompatible-pointer-types-discards-qualifiers',
|
|
||||||
'-Winit-self',
|
'-Winit-self',
|
||||||
'-Wlogical-op',
|
'-Wlogical-op',
|
||||||
'-Wmaybe-uninitialized',
|
'-Wmaybe-uninitialized',
|
||||||
@ -113,6 +112,12 @@ warning_flags = [
|
|||||||
cc = meson.get_compiler('c')
|
cc = meson.get_compiler('c')
|
||||||
add_project_arguments(cc.get_supported_arguments(warning_flags), language : '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()
|
if not meson.is_cross_build()
|
||||||
add_project_arguments('-fstack-protector-strong', language : 'c')
|
add_project_arguments('-fstack-protector-strong', language : 'c')
|
||||||
endif
|
endif
|
||||||
|
@ -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 @@
|
|
@ -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,
|
|
||||||
],
|
|
||||||
)
|
|
@ -79,5 +79,17 @@ if get_option('tests')
|
|||||||
install_dir : installed_test_bindir,
|
install_dir : installed_test_bindir,
|
||||||
)
|
)
|
||||||
test('optionrom-self-test', e, env : testdatadirs) # added to installed-tests
|
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
|
endif
|
||||||
|
@ -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,
|
|
||||||
],
|
|
||||||
)
|
|
@ -56,5 +56,4 @@ if get_option('tests')
|
|||||||
],
|
],
|
||||||
c_args : cargs
|
c_args : cargs
|
||||||
)
|
)
|
||||||
subdir('fuzzing')
|
|
||||||
endif
|
endif
|
||||||
|
1
plugins/tpm-eventlog/fuzzing/v2.bin
Normal file
1
plugins/tpm-eventlog/fuzzing/v2.bin
Normal file
@ -0,0 +1 @@
|
|||||||
|
Spec ID Event03
|
@ -98,11 +98,15 @@ if get_option('man')
|
|||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
run_target('fuzz-tpm-eventlog',
|
if honggfuzz.found()
|
||||||
command: [
|
run_target('fuzz-tpm-eventlog',
|
||||||
join_paths(meson.source_root(), 'contrib/afl-fuzz.py'),
|
command: [
|
||||||
'-i', join_paths(meson.current_source_dir(), 'tests'),
|
honggfuzz,
|
||||||
'-o', join_paths(meson.current_build_dir(), 'findings'),
|
'--input', join_paths(meson.current_source_dir(), 'fuzzing'),
|
||||||
fwupdtpmevlog,
|
'--output', join_paths(meson.current_build_dir(), 'fuzzing-corpus'),
|
||||||
],
|
'--workspace', join_paths(meson.current_build_dir(), 'fuzzing-findings'),
|
||||||
)
|
'--verifier',
|
||||||
|
'--', fwupdtpmevlog, '___FILE___',
|
||||||
|
],
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
@ -137,12 +137,15 @@ if get_option('man')
|
|||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
run_target('fuzz-efidbx',
|
if honggfuzz.found()
|
||||||
command: [
|
run_target('fuzz-efidbx',
|
||||||
join_paths(meson.source_root(), 'contrib/afl-fuzz.py'),
|
command: [
|
||||||
'-i', join_paths(meson.current_source_dir(), 'fuzzing'),
|
honggfuzz,
|
||||||
'-o', join_paths(meson.current_build_dir(), 'findings'),
|
'--input', join_paths(meson.current_source_dir(), 'fuzzing'),
|
||||||
'--command', uefi_dbx_fuzzer,
|
'--output', join_paths(meson.current_build_dir(), 'fuzzing-corpus'),
|
||||||
fwupdtool,
|
'--workspace', join_paths(meson.current_build_dir(), 'fuzzing-findings'),
|
||||||
],
|
'--verifier',
|
||||||
)
|
'--', uefi_dbx_fuzzer, '___FILE___',
|
||||||
|
],
|
||||||
|
)
|
||||||
|
endif
|
||||||
|
@ -1,58 +1,236 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2019 Richard Hughes <richard@hughsie.com>
|
* Copyright (C) 2019-2020 Richard Hughes <richard@hughsie.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: LGPL-2.1+
|
* SPDX-License-Identifier: LGPL-2.1+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include "fu-common.h"
|
#include <glib/gi18n.h>
|
||||||
#include "fu-srec-firmware.h"
|
#include <locale.h>
|
||||||
#include "fu-ihex-firmware.h"
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#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
|
int
|
||||||
main (int argc, char **argv)
|
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;
|
g_autoptr(GError) error = NULL;
|
||||||
gsize sz = 0;
|
g_autoptr(GPtrArray) firmware_types = NULL;
|
||||||
const guint8 *buf;
|
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 */
|
setlocale (LC_ALL, "");
|
||||||
if (argc != 2) {
|
|
||||||
g_printerr ("firmware filename required\n");
|
bindtextdomain (GETTEXT_PACKAGE, FWUPD_LOCALEDIR);
|
||||||
return 2;
|
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 */
|
/* args */
|
||||||
blob = fu_common_get_contents_bytes (argv[1], &error);
|
if (self->verbose) {
|
||||||
if (blob == NULL) {
|
g_setenv ("G_MESSAGES_DEBUG", "all", FALSE);
|
||||||
g_printerr ("failed to load file: %s\n", error->message);
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
buf = g_bytes_get_data (blob, &sz);
|
|
||||||
if (sz < 2) {
|
/* get all parser objects */
|
||||||
g_printerr ("firmware invalid\n");
|
firmware_types = fu_engine_get_firmware_gtype_ids (self->engine);
|
||||||
return 2;
|
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 ();
|
/* no args */
|
||||||
} else if (buf[0] == ':') {
|
if (argc >= 2) {
|
||||||
firmware = fu_ihex_firmware_new ();
|
gint rc = 0;
|
||||||
} else {
|
for (gint i = 1; i < argc; i++) {
|
||||||
g_printerr ("firmware invalid type, expected .srec or .hex\n");
|
g_autoptr(GBytes) blob = NULL;
|
||||||
return 2;
|
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,
|
for (;;) {
|
||||||
FWUPD_INSTALL_FLAG_IGNORE_VID_PID |
|
gsize len = 0;
|
||||||
FWUPD_INSTALL_FLAG_IGNORE_CHECKSUM,
|
guint8 *buf = NULL;
|
||||||
&error)) {
|
g_autoptr(GBytes) blob = NULL;
|
||||||
g_printerr ("failed to parse file: %s\n", error->message);
|
#ifdef HAVE_HF_ITER
|
||||||
return 3;
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
BIN
src/fuzzing/bcm57xx-stage1.bin
Normal file
BIN
src/fuzzing/bcm57xx-stage1.bin
Normal file
Binary file not shown.
18
src/fuzzing/bcm57xx.builder.xml
Normal file
18
src/fuzzing/bcm57xx.builder.xml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<firmware gtype="FuBcm57xxFirmware">
|
||||||
|
<version>1.2.3</version>
|
||||||
|
<image gtype="FuBcm57xxStage1Image">
|
||||||
|
<version>7.8.9</version>
|
||||||
|
<id>stage1</id>
|
||||||
|
<idx>0x01</idx>
|
||||||
|
<filename>bcm57xx-stage1.bin</filename>
|
||||||
|
</image>
|
||||||
|
<image gtype="FuBcm57xxStage2Image">
|
||||||
|
<id>stage2</id>
|
||||||
|
<data/> <!-- empty! -->
|
||||||
|
</image>
|
||||||
|
<image gtype="FuBcm57xxDictImage">
|
||||||
|
<id>ape</id>
|
||||||
|
<addr>0x7</addr>
|
||||||
|
<data>aGVsbG8gd29ybGQ=</data> <!-- base64 -->
|
||||||
|
</image>
|
||||||
|
</firmware>
|
19
src/fuzzing/cros-ec.builder.xml
Normal file
19
src/fuzzing/cros-ec.builder.xml
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<firmware gtype="FuCrosEcFirmware">
|
||||||
|
<base>0x3000</base>
|
||||||
|
<image>
|
||||||
|
<id>RO_FRID</id>
|
||||||
|
<data>Y2hlZXNlX3YxLjEuMTc1NS00ZGE5NTIwICAgICAgICA=</data>
|
||||||
|
</image>
|
||||||
|
<image>
|
||||||
|
<id>RW_FWID</id>
|
||||||
|
<data>Y2hlZXNlX3YxLjEuMTc1NS00ZGE5NTIwICAgICAgICA=</data>
|
||||||
|
</image>
|
||||||
|
<image>
|
||||||
|
<id>EC_RO</id>
|
||||||
|
<data>Y2hlZXNlX3YxLjEuMTc1NS00ZGE5NTIwICAgICAgICA=</data>
|
||||||
|
</image>
|
||||||
|
<image>
|
||||||
|
<id>EC_RW</id>
|
||||||
|
<data>Y2hlZXNlX3YxLjEuMTc1NS00ZGE5NTIwICAgICAgICA=</data>
|
||||||
|
</image>
|
||||||
|
</firmware>
|
BIN
src/fuzzing/firmware/bcm57xx.bin
Normal file
BIN
src/fuzzing/firmware/bcm57xx.bin
Normal file
Binary file not shown.
BIN
src/fuzzing/firmware/cros-ec.bin
Normal file
BIN
src/fuzzing/firmware/cros-ec.bin
Normal file
Binary file not shown.
BIN
src/fuzzing/firmware/ebitdo.dat
Normal file
BIN
src/fuzzing/firmware/ebitdo.dat
Normal file
Binary file not shown.
BIN
src/fuzzing/firmware/fmap.bin
Normal file
BIN
src/fuzzing/firmware/fmap.bin
Normal file
Binary file not shown.
BIN
src/fuzzing/firmware/rmi-0x.img
Normal file
BIN
src/fuzzing/firmware/rmi-0x.img
Normal file
Binary file not shown.
BIN
src/fuzzing/firmware/rmi-10.img
Normal file
BIN
src/fuzzing/firmware/rmi-10.img
Normal file
Binary file not shown.
1
src/fuzzing/firmware/solokey.json
Normal file
1
src/fuzzing/firmware/solokey.json
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"firmware": "OjA0NDAwMDAwM0RFRjIwRjA4MAo6MDAwMDAwMDFGRgo=", "signature": "aGVsbG8gd29ybGQ="}
|
BIN
src/fuzzing/firmware/synaprom.bin
Normal file
BIN
src/fuzzing/firmware/synaprom.bin
Normal file
Binary file not shown.
9
src/fuzzing/firmware/wacom.wac
Normal file
9
src/fuzzing/firmware/wacom.wac
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
WACOM2080080000009414E080400000009414A3F
|
||||||
|
WA10800800067
|
||||||
|
S00B00004F616B2E73726563FE
|
||||||
|
S70508038BD58F
|
||||||
|
|
||||||
|
WA2080400001F
|
||||||
|
S00B00004F616B2E73726563FE
|
||||||
|
S70508070BD50B
|
||||||
|
|
10
src/fuzzing/fmap.builder.xml
Normal file
10
src/fuzzing/fmap.builder.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<firmware gtype="FuFmapFirmware">
|
||||||
|
<image>
|
||||||
|
<id>FMAP</id>
|
||||||
|
<data>aGVsbG8gd29ybGQ=</data>
|
||||||
|
</image>
|
||||||
|
<image>
|
||||||
|
<id>TEST</id>
|
||||||
|
<data>V29ybGQh</data>
|
||||||
|
</image>
|
||||||
|
</firmware>
|
@ -1,17 +1,25 @@
|
|||||||
run_target('fuzz-smbios',
|
if honggfuzz.found()
|
||||||
command: [
|
run_target('fuzz-smbios',
|
||||||
join_paths(meson.source_root(), 'contrib/afl-fuzz.py'),
|
command: [
|
||||||
'-i', join_paths(meson.current_source_dir(), 'smbios'),
|
honggfuzz,
|
||||||
'-o', join_paths(meson.current_build_dir(), '..', 'findings-smbios'),
|
'--input', join_paths(meson.current_source_dir(), 'smbios'),
|
||||||
'--command', 'smbios-dump',
|
'--output', join_paths(meson.current_build_dir(), 'smbios-corpus'),
|
||||||
fwupdtool,
|
'--workspace', join_paths(meson.current_build_dir(), 'smbios-findings'),
|
||||||
],
|
'--verifier',
|
||||||
)
|
'--rlimit_rss', '10',
|
||||||
run_target('fuzz-firmware',
|
'--', fwupdtool, 'smbios-dump', '___FILE___',
|
||||||
command: [
|
],
|
||||||
join_paths(meson.source_root(), 'contrib/afl-fuzz.py'),
|
)
|
||||||
'-i', join_paths(meson.current_source_dir(), 'firmware'),
|
run_target('fuzz-firmware',
|
||||||
'-o', join_paths(meson.current_build_dir(), '..', 'findings-firmware'),
|
command: [
|
||||||
fwupd_firmware_dump,
|
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
|
||||||
|
7
src/fuzzing/synaprom.builder.xml
Normal file
7
src/fuzzing/synaprom.builder.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<firmware gtype="FuSynapromFirmware">
|
||||||
|
<version>1.2</version>
|
||||||
|
<image>
|
||||||
|
<product_id>0x42</product_id>
|
||||||
|
<data>aGVsbG8gd29ybGQ=</data> <!-- base64 -->
|
||||||
|
</image>
|
||||||
|
</firmware>
|
@ -307,14 +307,13 @@ if get_option('tests')
|
|||||||
],
|
],
|
||||||
)
|
)
|
||||||
test('fu-self-test', e, is_parallel:false, timeout:180)
|
test('fu-self-test', e, is_parallel:false, timeout:180)
|
||||||
endif
|
|
||||||
|
|
||||||
if get_option('tests')
|
|
||||||
# for fuzzing
|
# for fuzzing
|
||||||
fwupd_firmware_dump = executable(
|
fwupd_firmware_dump = executable(
|
||||||
'fwupd-firmware-dump',
|
'fwupd-firmware-dump',
|
||||||
sources : [
|
sources : [
|
||||||
'fu-firmware-dump.c',
|
'fu-firmware-dump.c',
|
||||||
|
daemon_src,
|
||||||
],
|
],
|
||||||
include_directories : [
|
include_directories : [
|
||||||
root_incdir,
|
root_incdir,
|
||||||
@ -322,8 +321,7 @@ if get_option('tests')
|
|||||||
fwupdplugin_incdir,
|
fwupdplugin_incdir,
|
||||||
],
|
],
|
||||||
dependencies : [
|
dependencies : [
|
||||||
libxmlb,
|
daemon_dep,
|
||||||
gio,
|
|
||||||
],
|
],
|
||||||
link_with : [
|
link_with : [
|
||||||
fwupd,
|
fwupd,
|
||||||
@ -332,6 +330,4 @@ if get_option('tests')
|
|||||||
)
|
)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if get_option('tests')
|
subdir('fuzzing')
|
||||||
subdir('fuzzing')
|
|
||||||
endif
|
|
||||||
|
Loading…
Reference in New Issue
Block a user