mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-24 21:54:01 +00:00
sandbox: Add libfuzzer integration
Add an implementation of LLVMFuzzerTestOneInput() that starts the sandbox on a secondary thread and exposes a function to synchronize the generation of fuzzing inputs with their consumption by the sandbox. Signed-off-by: Andrew Scull <ascull@google.com> Reviewed-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
001c39a196
commit
d9962b12f2
3 changed files with 98 additions and 0 deletions
|
@ -19,6 +19,9 @@ SANITIZERS :=
|
|||
ifdef CONFIG_ASAN
|
||||
SANITIZERS += -fsanitize=address
|
||||
endif
|
||||
ifdef CONFIG_FUZZ
|
||||
SANITIZERS += -fsanitize=fuzzer
|
||||
endif
|
||||
KBUILD_CFLAGS += $(SANITIZERS)
|
||||
|
||||
cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds $(u-boot-init) \
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <getopt.h>
|
||||
#include <setjmp.h>
|
||||
#include <signal.h>
|
||||
|
@ -26,6 +27,7 @@
|
|||
#include <linux/compiler_attributes.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/fuzzing_engine.h>
|
||||
#include <asm/getopt.h>
|
||||
#include <asm/main.h>
|
||||
#include <asm/sections.h>
|
||||
|
@ -1003,7 +1005,75 @@ void os_relaunch(char *argv[])
|
|||
os_exit(1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_FUZZ
|
||||
static void *fuzzer_thread(void * ptr)
|
||||
{
|
||||
char cmd[64];
|
||||
char *argv[5] = {"./u-boot", "-T", "-c", cmd, NULL};
|
||||
const char *fuzz_test;
|
||||
|
||||
/* Find which test to run from an environment variable. */
|
||||
fuzz_test = getenv("UBOOT_SB_FUZZ_TEST");
|
||||
if (!fuzz_test)
|
||||
os_abort();
|
||||
|
||||
snprintf(cmd, sizeof(cmd), "fuzz %s", fuzz_test);
|
||||
|
||||
sandbox_main(4, argv);
|
||||
os_abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool fuzzer_initialized = false;
|
||||
static pthread_mutex_t fuzzer_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static pthread_cond_t fuzzer_cond = PTHREAD_COND_INITIALIZER;
|
||||
static const uint8_t *fuzzer_data;
|
||||
static size_t fuzzer_size;
|
||||
|
||||
int sandbox_fuzzing_engine_get_input(const uint8_t **data, size_t *size)
|
||||
{
|
||||
if (!fuzzer_initialized)
|
||||
return -ENOSYS;
|
||||
|
||||
/* Tell the main thread we need new inputs then wait for them. */
|
||||
pthread_mutex_lock(&fuzzer_mutex);
|
||||
pthread_cond_signal(&fuzzer_cond);
|
||||
pthread_cond_wait(&fuzzer_cond, &fuzzer_mutex);
|
||||
*data = fuzzer_data;
|
||||
*size = fuzzer_size;
|
||||
pthread_mutex_unlock(&fuzzer_mutex);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
static pthread_t tid;
|
||||
|
||||
pthread_mutex_lock(&fuzzer_mutex);
|
||||
|
||||
/* Initialize the sandbox on another thread. */
|
||||
if (!fuzzer_initialized) {
|
||||
fuzzer_initialized = true;
|
||||
if (pthread_create(&tid, NULL, fuzzer_thread, NULL))
|
||||
os_abort();
|
||||
pthread_cond_wait(&fuzzer_cond, &fuzzer_mutex);
|
||||
}
|
||||
|
||||
/* Hand over the input. */
|
||||
fuzzer_data = data;
|
||||
fuzzer_size = size;
|
||||
pthread_cond_signal(&fuzzer_cond);
|
||||
|
||||
/* Wait for the inputs to be finished with. */
|
||||
pthread_cond_wait(&fuzzer_cond, &fuzzer_mutex);
|
||||
pthread_mutex_unlock(&fuzzer_mutex);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
return sandbox_main(argc, argv);
|
||||
}
|
||||
#endif
|
||||
|
|
25
arch/sandbox/include/asm/fuzzing_engine.h
Normal file
25
arch/sandbox/include/asm/fuzzing_engine.h
Normal file
|
@ -0,0 +1,25 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (c) 2022 Google, Inc.
|
||||
* Written by Andrew Scull <ascull@google.com>
|
||||
*/
|
||||
|
||||
#ifndef __ASM_FUZZING_ENGINE_H
|
||||
#define __ASM_FUZZING_ENGINE_H
|
||||
|
||||
/** Function to get fuzzing engine input data. */
|
||||
/**
|
||||
* sandbox_fuzzing_engine_get_input() - get an input from the sandbox fuzzing
|
||||
* engine
|
||||
*
|
||||
* The function will return a pointer to the input data and the size of the
|
||||
* data pointed to. The pointer will remain valid until the next invocation of
|
||||
* this function.
|
||||
*
|
||||
* @data: output pointer to input data
|
||||
* @size output size of input data
|
||||
* Return: 0 if OK, -ve on error
|
||||
*/
|
||||
int sandbox_fuzzing_engine_get_input(const uint8_t **data, size_t *size);
|
||||
|
||||
#endif /* __ASM_FUZZING_ENGINE_H */
|
Loading…
Reference in a new issue