mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 23:51:33 +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
|
ifdef CONFIG_ASAN
|
||||||
SANITIZERS += -fsanitize=address
|
SANITIZERS += -fsanitize=address
|
||||||
endif
|
endif
|
||||||
|
ifdef CONFIG_FUZZ
|
||||||
|
SANITIZERS += -fsanitize=fuzzer
|
||||||
|
endif
|
||||||
KBUILD_CFLAGS += $(SANITIZERS)
|
KBUILD_CFLAGS += $(SANITIZERS)
|
||||||
|
|
||||||
cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds $(u-boot-init) \
|
cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds $(u-boot-init) \
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -26,6 +27,7 @@
|
||||||
#include <linux/compiler_attributes.h>
|
#include <linux/compiler_attributes.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#include <asm/fuzzing_engine.h>
|
||||||
#include <asm/getopt.h>
|
#include <asm/getopt.h>
|
||||||
#include <asm/main.h>
|
#include <asm/main.h>
|
||||||
#include <asm/sections.h>
|
#include <asm/sections.h>
|
||||||
|
@ -1003,7 +1005,75 @@ void os_relaunch(char *argv[])
|
||||||
os_exit(1);
|
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[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
return sandbox_main(argc, 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