Merge branch '2022-06-23-fuzzing-and-asan-for-sandbox' into next

To quote the author:
This series introduces ASAN and a basic fuzzing infrastructure that
works with sandbox. The example fuzz test towards the end of the series
will find something pretty quickly. That something is fixed by the
series "virtio: Harden and test vring" that needs to be applied for the
final patch in this series.

There is some refactoring to stop using '.' prefixed sections. ELF
defines sections with names that contain anything that isn't
alphanumeric or an underscore as being for system use which means
clang's ASAN instrumentation happily add redzones between the contained
objects. That's not what we want for things like linker lists where the
linker script has carefully placed the sections contiguously. By
renaming the sections, clang sees them as user sections and doesn't add
instrumentation.

ASAN is left disabled by default as there are still some tests that it
triggers on and will need some more investigation to fix. It can be
enabled with CONFIG_ASAN or passing `-a ASAN` to buildman.
This commit is contained in:
Tom Rini 2022-06-23 14:24:24 -04:00
commit 3e00721b3b
77 changed files with 673 additions and 151 deletions

View file

@ -473,6 +473,12 @@ stages:
BUILDMAN: "imx8"
keystone2_keystone3:
BUILDMAN: "k2 k3"
sandbox_asan:
BUILDMAN: "sandbox"
OVERRIDE: "-a ASAN"
sandbox_clang_asan:
BUILDMAN: "sandbox"
OVERRIDE: "-O clang-13 -a ASAN"
samsung_socfpga:
BUILDMAN: "samsung socfpga"
sun4i:

16
Kconfig
View file

@ -154,6 +154,22 @@ config CC_COVERAGE
Enabling this option will pass "--coverage" to gcc to compile
and link code instrumented for coverage analysis.
config ASAN
bool "Enable AddressSanitizer"
depends on SANDBOX
help
Enables AddressSanitizer to discover out-of-bounds accesses,
use-after-free, double-free and memory leaks.
config FUZZ
bool "Enable fuzzing"
depends on CC_IS_CLANG
depends on DM_FUZZING_ENGINE
select ASAN
help
Enables the fuzzing infrastructure to generate fuzzing data and run
fuzz tests.
config CC_HAS_ASM_INLINE
def_bool $(success,echo 'void foo(void) { asm inline (""); }' | $(CC) -x c - -c -o /dev/null)

View file

@ -135,6 +135,7 @@ config SANDBOX
select BZIP2
select CMD_POWEROFF
select DM
select DM_FUZZING_ENGINE
select DM_GPIO
select DM_I2C
select DM_KEYBOARD
@ -170,6 +171,7 @@ config SANDBOX
imply CRC32_VERIFY
imply FAT_WRITE
imply FIRMWARE
imply FUZZING_ENGINE_SANDBOX
imply HASH_VERIFY
imply LZMA
imply TEE

View file

@ -39,8 +39,8 @@ SECTIONS
}
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = ALIGN(4);

View file

@ -141,11 +141,11 @@ endif
# limit ourselves to the sections we want in the .bin.
ifdef CONFIG_ARM64
OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .data \
-j .u_boot_list -j .rela.dyn -j .got -j .got.plt \
-j __u_boot_list -j .rela.dyn -j .got -j .got.plt \
-j .binman_sym_table -j .text_rest
else
OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .hash \
-j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn \
-j .data -j .got -j .got.plt -j __u_boot_list -j .rel.dyn \
-j .binman_sym_table -j .text_rest
endif

View file

@ -29,8 +29,8 @@ SECTIONS
.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
} > .sram
. = ALIGN(4);

View file

@ -38,8 +38,8 @@ SECTIONS
.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
} > .sram
. = ALIGN(4);

View file

@ -46,9 +46,9 @@ SECTIONS
} >.sram
#endif
.u_boot_list : {
__u_boot_list : {
. = ALIGN(8);
KEEP(*(SORT(.u_boot_list*)));
KEEP(*(SORT(__u_boot_list*)));
} >.sram
.image_copy_end : {

View file

@ -109,8 +109,8 @@ SECTIONS
. = .;
. = ALIGN(8);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = ALIGN(8);

View file

@ -32,8 +32,8 @@ SECTIONS
}
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = ALIGN(4);

View file

@ -15,7 +15,7 @@ ENTRY(_start)
SECTIONS
{
#ifndef CONFIG_CMDLINE
/DISCARD/ : { *(.u_boot_list_2_cmd_*) }
/DISCARD/ : { *(__u_boot_list_2_cmd_*) }
#endif
#if defined(CONFIG_ARMV7_SECURE_BASE) && defined(CONFIG_ARMV7_NONSEC)
/*
@ -149,8 +149,8 @@ SECTIONS
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = ALIGN(4);

View file

@ -29,7 +29,7 @@ SECTIONS
.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
. = ALIGN(4);
.u_boot_list : { KEEP(*(SORT(.u_boot_list*))) } > .sram
__u_boot_list : { KEEP(*(SORT(__u_boot_list*))) } > .sram
. = ALIGN(4);
__image_copy_end = .;

View file

@ -36,7 +36,7 @@ SECTIONS
.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
. = ALIGN(4);
.u_boot_list : { KEEP(*(SORT(.u_boot_list*))) } > .sram
__u_boot_list : { KEEP(*(SORT(__u_boot_list*))) } > .sram
. = ALIGN(4);
__image_copy_end = .;

View file

@ -33,8 +33,8 @@ SECTIONS
.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
} >.sram
. = ALIGN(4);

View file

@ -41,8 +41,8 @@ SECTIONS
.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.nor
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
} > .nor
. = ALIGN(4);

View file

@ -39,9 +39,9 @@ SECTIONS
*(.data*)
}
.u_boot_list : {
__u_boot_list : {
. = ALIGN(8);
KEEP(*(SORT(.u_boot_list*)));
KEEP(*(SORT(__u_boot_list*)));
}
.image_copy_end : {

View file

@ -37,8 +37,8 @@ SECTIONS
} > .sram
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
} > .sram
. = ALIGN(4);

View file

@ -54,8 +54,8 @@ SECTIONS
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = ALIGN(4);

View file

@ -60,8 +60,8 @@ SECTIONS
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = .;

View file

@ -37,8 +37,8 @@ SECTIONS
}
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
__init_end = . ;

View file

@ -41,8 +41,8 @@ SECTIONS
}
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
__init_end = . ;

View file

@ -65,6 +65,6 @@ PLATFORM_CPPFLAGS += -msoft-float
KBUILD_LDFLAGS += -G 0 -static -n -nostdlib
PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
LDFLAGS_FINAL += --gc-sections
OBJCOPYFLAGS += -j .text -j .rodata -j .data -j .u_boot_list
OBJCOPYFLAGS += -j .text -j .rodata -j .data -j __u_boot_list
LDFLAGS_STANDALONE += --gc-sections

View file

@ -29,8 +29,8 @@ SECTIONS
#if defined(CONFIG_SPL_DM) || defined(CONFIG_SPL_LOADER_SUPPORT)
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
} > .spl_mem
#endif

View file

@ -33,8 +33,8 @@ SECTIONS
}
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = ALIGN(4);

View file

@ -32,8 +32,8 @@ SECTIONS
*/
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
/* INIT DATA sections - "Small" data (see the gcc -G option)

View file

@ -42,8 +42,8 @@ SECTIONS
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}

View file

@ -50,8 +50,8 @@ SECTIONS
_edata = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = .;

View file

@ -67,8 +67,8 @@ SECTIONS
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = .;

View file

@ -40,8 +40,8 @@ SECTIONS
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
} > .spl_mem
. = ALIGN(4);

View file

@ -44,8 +44,8 @@ SECTIONS
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = ALIGN(4);

View file

@ -15,8 +15,19 @@ PLATFORM_LIBS += $(shell $(SDL_CONFIG) --libs)
PLATFORM_CPPFLAGS += $(shell $(SDL_CONFIG) --cflags)
endif
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) \
$(KBUILD_LDFLAGS:%=-Wl,%)$(LTO_FINAL_LDFLAGS) \
$(KBUILD_LDFLAGS:%=-Wl,%) \
$(SANITIZERS) \
$(LTO_FINAL_LDFLAGS) \
-Wl,--whole-archive \
$(u-boot-main) \
$(u-boot-keep-syms-lto) \
@ -24,7 +35,9 @@ cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds $(u-boot-init) \
$(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map
cmd_u-boot-spl = (cd $(obj) && $(CC) -o $(SPL_BIN) -Wl,-T u-boot-spl.lds \
$(KBUILD_LDFLAGS:%=-Wl,%) $(LTO_FINAL_LDFLAGS) \
$(KBUILD_LDFLAGS:%=-Wl,%) \
$(SANITIZERS) \
$(LTO_FINAL_LDFLAGS) \
$(patsubst $(obj)/%,%,$(u-boot-spl-init)) \
-Wl,--whole-archive \
$(patsubst $(obj)/%,%,$(u-boot-spl-main)) \
@ -44,13 +57,13 @@ EFI_TARGET := --target=efi-app-ia32
else ifeq ($(HOST_ARCH),$(HOST_ARCH_AARCH64))
EFI_LDS := ${SRCDIR}/../../../arch/arm/lib/elf_aarch64_efi.lds
OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .data \
-j .u_boot_list -j .rela.dyn -j .got -j .got.plt \
-j __u_boot_list -j .rela.dyn -j .got -j .got.plt \
-j .binman_sym_table -j .text_rest \
-j .efi_runtime -j .efi_runtime_rel
else ifeq ($(HOST_ARCH),$(HOST_ARCH_ARM))
EFI_LDS := ${SRCDIR}/../../../arch/arm/lib/elf_arm_efi.lds
OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .hash \
-j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn \
-j .data -j .got -j .got.plt -j __u_boot_list -j .rel.dyn \
-j .binman_sym_table -j .text_rest \
-j .efi_runtime -j .efi_runtime_rel
else ifeq ($(HOST_ARCH),$(HOST_ARCH_RISCV32))

View file

@ -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,7 +27,9 @@
#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>
#include <asm/state.h>
#include <os.h>
@ -1001,3 +1004,76 @@ void os_relaunch(char *argv[])
execv(argv[0], 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

View file

@ -453,7 +453,7 @@ void sandbox_reset(void)
os_relaunch(os_argv);
}
int main(int argc, char *argv[])
int sandbox_main(int argc, char *argv[])
{
struct sandbox_state *state;
void * text_base;

View file

@ -9,8 +9,8 @@ SECTIONS
{
. = ALIGN(32);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
/* Private data for devices with OF_PLATDATA_RT */
@ -22,9 +22,9 @@ SECTIONS
}
_u_boot_sandbox_getopt : {
*(.u_boot_sandbox_getopt_start)
KEEP(*(.u_boot_sandbox_getopt))
*(.u_boot_sandbox_getopt_end)
*(_u_boot_sandbox_getopt_start)
KEEP(*(_u_boot_sandbox_getopt))
*(_u_boot_sandbox_getopt_end)
}
}

View file

@ -9,42 +9,40 @@ SECTIONS
{
. = ALIGN(32);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
_u_boot_sandbox_getopt : {
*(.u_boot_sandbox_getopt_start)
*(.u_boot_sandbox_getopt)
*(.u_boot_sandbox_getopt_end)
*(_u_boot_sandbox_getopt_start)
*(_u_boot_sandbox_getopt)
*(_u_boot_sandbox_getopt_end)
}
.__efi_runtime_start : {
*(.__efi_runtime_start)
efi_runtime_start : {
*(___efi_runtime_start)
}
.efi_runtime : {
efi_runtime : {
*(efi_runtime_text)
*(efi_runtime_data)
}
.__efi_runtime_stop : {
*(.__efi_runtime_stop)
efi_runtime_stop : {
*(___efi_runtime_stop)
}
.efi_runtime_rel_start :
{
*(.__efi_runtime_rel_start)
efi_runtime_rel_start : {
*(___efi_runtime_rel_start)
}
.efi_runtime_rel : {
efi_runtime_rel : {
*(.relefi_runtime_text)
*(.relefi_runtime_data)
}
.efi_runtime_rel_stop :
{
*(.__efi_runtime_rel_stop)
efi_runtime_rel_stop : {
*(___efi_runtime_rel_stop)
}
.dynsym :

View file

@ -92,6 +92,10 @@
};
};
fuzzing-engine {
compatible = "sandbox,fuzzing-engine";
};
reboot-mode0 {
compatible = "reboot-mode-gpio";
gpios = <&gpio_c 0 GPIO_ACTIVE_HIGH>, <&gpio_c 1 GPIO_ACTIVE_HIGH>;

View 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 */

View file

@ -44,7 +44,7 @@ struct sandbox_cmdline_option {
.callback = sandbox_cmdline_cb_##f, \
}; \
/* Ppointer to the struct in a special section for the linker script */ \
static __used __section(".u_boot_sandbox_getopt") \
static __used __section("_u_boot_sandbox_getopt") \
struct sandbox_cmdline_option \
*sandbox_cmdline_option_##f##_ptr = \
&sandbox_cmdline_option_##f

View file

@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2022 Google, Inc.
* Written by Andrew Scull <ascull@google.com>
*/
#ifndef __ASM_SANDBOX_MAIN_H
#define __ASM_SANDBOX_MAIN_H
/**
* sandbox_main() - main entrypoint for sandbox
*
* @argc: the number of arguments passed to the program
* @argv: array of argc+1 pointers, of which the last one is null
*/
int sandbox_main(int argc, char *argv[]);
#endif /* __ASM_SANDBOX_MAIN_H */

View file

@ -17,7 +17,7 @@ static inline struct sandbox_cmdline_option **
__u_boot_sandbox_option_start(void)
{
static char start[0] __aligned(4) __attribute__((unused))
__section(".u_boot_sandbox_getopt_start");
__section("_u_boot_sandbox_getopt_start");
return (struct sandbox_cmdline_option **)&start;
}
@ -26,7 +26,7 @@ static inline struct sandbox_cmdline_option **
__u_boot_sandbox_option_end(void)
{
static char end[0] __aligned(4) __attribute__((unused))
__section(".u_boot_sandbox_getopt_end");
__section("_u_boot_sandbox_getopt_end");
return (struct sandbox_cmdline_option **)&end;
}

View file

@ -5,9 +5,9 @@
*/
#include <linux/compiler.h>
char __efi_runtime_start[0] __section(".__efi_runtime_start");
char __efi_runtime_stop[0] __section(".__efi_runtime_stop");
char __efi_runtime_start[0] __section("___efi_runtime_start");
char __efi_runtime_stop[0] __section("___efi_runtime_stop");
char __efi_runtime_rel_start[0]
__section(".__efi_runtime_rel_start");
__section("___efi_runtime_rel_start");
char __efi_runtime_rel_stop[0]
__section(".__efi_runtime_rel_stop");
__section("___efi_runtime_rel_stop");

View file

@ -70,8 +70,8 @@ SECTIONS
} >ram
PROVIDE (_egot = .);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
} >ram
PROVIDE (__init_end = .);

View file

@ -12,7 +12,7 @@ ENTRY(_start)
SECTIONS
{
#ifndef CONFIG_CMDLINE
/DISCARD/ : { *(.u_boot_list_2_cmd_*) }
/DISCARD/ : { *(__u_boot_list_2_cmd_*) }
#endif
#ifdef CONFIG_SYS_TEXT_BASE
@ -41,8 +41,8 @@ SECTIONS
. = ALIGN(4);
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = ALIGN(4);

View file

@ -12,7 +12,7 @@ ENTRY(_start)
SECTIONS
{
#ifndef CONFIG_CMDLINE
/DISCARD/ : { *(.u_boot_list_2_cmd_*) }
/DISCARD/ : { *(__u_boot_list_2_cmd_*) }
#endif
. = IMAGE_TEXT_BASE; /* Location of bootcode in flash */
@ -25,8 +25,8 @@ SECTIONS
. = ALIGN(4);
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = ALIGN(4);

View file

@ -12,7 +12,7 @@ ENTRY(_start)
SECTIONS
{
#ifndef CONFIG_CMDLINE
/DISCARD/ : { *(.u_boot_list_2_cmd_*) }
/DISCARD/ : { *(__u_boot_list_2_cmd_*) }
#endif
. = CONFIG_SYS_TEXT_BASE; /* Location of bootcode in flash */
@ -39,8 +39,8 @@ SECTIONS
. = ALIGN(4);
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = ALIGN(4);

View file

@ -51,7 +51,7 @@ SECTIONS
/* U-Boot lists and device tree */
. = ALIGN(8);
*(SORT(.u_boot_list*));
*(SORT(__u_boot_list*));
. = ALIGN(8);
*(.dtb*);
}
@ -69,7 +69,7 @@ SECTIONS
*(.data.rel.local)
*(.data.rel.ro)
*(.data.rel*)
*(.rel.u_boot_list*)
*(.rel__u_boot_list*)
}
. = ALIGN(4096);
.reloc : /* This is the PECOFF .reloc section! */

View file

@ -50,7 +50,7 @@ SECTIONS
/* U-Boot lists and device tree */
. = ALIGN(8);
*(SORT(.u_boot_list*));
*(SORT(__u_boot_list*));
. = ALIGN(8);
*(.dtb*);
}
@ -63,7 +63,7 @@ SECTIONS
*(.rela.data*)
*(.rela.got)
*(.rela.stab)
*(.rela.u_boot_list*)
*(.rela__u_boot_list*)
}
. = ALIGN(4096);

View file

@ -49,7 +49,7 @@ SECTIONS
RELOCATE1(text);
RELOCATE1(rodata);
RELOCATE1(data);
RELOCATE1(u_boot_list);
RELOCATE_USER1(__u_boot_list);
__reloc_table_end = ABSOLUTE(.);
}
@ -78,7 +78,7 @@ SECTIONS
SECTION_text(XTENSA_SYS_TEXT_ADDR, FOLLOWING(.DoubleExceptionVector.text))
SECTION_rodata(ALIGN(16), FOLLOWING(.text))
SECTION_u_boot_list(ALIGN(16), FOLLOWING(.rodata))
SECTION_data(ALIGN(16), FOLLOWING(.u_boot_list))
SECTION_data(ALIGN(16), FOLLOWING(__u_boot_list))
__reloc_end = .;
__init_end = .;

View file

@ -41,6 +41,11 @@
LONG(_##_sym_##_##_sec_##_end); \
LONG(LOADADDR(.##_sym_##.##_sec_));
#define RELOCATE_USER1(_sec_) \
LONG(_##_sec_##_start); \
LONG(_##_sec_##_end); \
LONG(LOADADDR(_sec_));
#define SECTION_VECTOR(_sym_, _sec_, _vma_, _lma_) \
.##_sym_##.##_sec_ _vma_ : _lma_ \
{ \
@ -100,11 +105,11 @@
}
#define SECTION_u_boot_list(_vma_, _lma_) \
.u_boot_list _vma_ : _lma_ \
__u_boot_list _vma_ : _lma_ \
{ \
_u_boot_list_start = ABSOLUTE(.); \
KEEP(*(SORT(.u_boot_list*))); \
_u_boot_list_end = ABSOLUTE(.); \
___u_boot_list_start = ABSOLUTE(.); \
KEEP(*(SORT(__u_boot_list*))); \
___u_boot_list_end = ABSOLUTE(.); \
}
#define SECTION_data(_vma_, _lma_) \

View file

@ -36,8 +36,8 @@ SECTIONS
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = ALIGN(4);

View file

@ -59,8 +59,8 @@ SECTIONS
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = .;

View file

@ -36,7 +36,7 @@ SECTIONS
.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
. = ALIGN(4);
.u_boot_list : { KEEP(*(SORT(.u_boot_list*))); } >.sram
__u_boot_list : { KEEP(*(SORT(__u_boot_list*))); } >.sram
. = ALIGN(4);
.rel.dyn : {

View file

@ -49,8 +49,8 @@ SECTIONS
. = .;
. = ALIGN(8);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = ALIGN(8);

View file

@ -32,8 +32,8 @@ SECTIONS
.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
} >.sram
. = ALIGN(4);

View file

@ -40,8 +40,8 @@ SECTIONS
} > ROM
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
/* Mark RAM's LMA */
. = ALIGN(4);

View file

@ -72,8 +72,8 @@ SECTIONS
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = ALIGN(4);

View file

@ -53,8 +53,8 @@ SECTIONS
. = .;
. = ALIGN(4);
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
. = ALIGN(4);

View file

@ -13,7 +13,7 @@ then the corresponding input section name is
::
.u_boot_list_ + 2_ + @_list + _2_ + @_entry
__u_boot_list_ + 2_ + @_list + _2_ + @_entry
and the C variable name is
@ -23,7 +23,7 @@ and the C variable name is
This ensures uniqueness for both input section and C variable name.
Note that the names differ only in the first character, "." for the
Note that the names differ only in the characters, "__" for the
section and "_" for the variable, so that the linker cannot confuse
section and symbol names. From now on, both names will be referred
to as
@ -63,11 +63,11 @@ iterated at least once.
::
.u_boot_list_2_array_1
.u_boot_list_2_array_2_first
.u_boot_list_2_array_2_second
.u_boot_list_2_array_2_third
.u_boot_list_2_array_3
__u_boot_list_2_array_1
__u_boot_list_2_array_2_first
__u_boot_list_2_array_2_second
__u_boot_list_2_array_2_third
__u_boot_list_2_array_3
If lists must be divided into sublists (e.g. for iterating only on
part of a list), one can simply give the list a name of the form
@ -129,17 +129,17 @@ the compiler cannot update the alignment of the linker_list item.
In the first case, an 8-byte 'fill' region is added::
.u_boot_list_2_driver_2_testbus_drv
__u_boot_list_2_driver_2_testbus_drv
0x0000000000270018 0x80 test/built-in.o
0x0000000000270018 _u_boot_list_2_driver_2_testbus_drv
.u_boot_list_2_driver_2_testfdt1_drv
__u_boot_list_2_driver_2_testfdt1_drv
0x0000000000270098 0x80 test/built-in.o
0x0000000000270098 _u_boot_list_2_driver_2_testfdt1_drv
*fill* 0x0000000000270118 0x8
.u_boot_list_2_driver_2_testfdt_drv
__u_boot_list_2_driver_2_testfdt_drv
0x0000000000270120 0x80 test/built-in.o
0x0000000000270120 _u_boot_list_2_driver_2_testfdt_drv
.u_boot_list_2_driver_2_testprobe_drv
__u_boot_list_2_driver_2_testprobe_drv
0x00000000002701a0 0x80 test/built-in.o
0x00000000002701a0 _u_boot_list_2_driver_2_testprobe_drv

View file

@ -169,8 +169,8 @@ by writing in u-boot.lds ($(srctree)/board/boardname/u-boot.lds) these
.. code-block:: c
.u_boot_list : {
KEEP(*(SORT(.u_boot_list*)));
__u_boot_list : {
KEEP(*(SORT(__u_boot_list*)));
}
Writing tests

View file

@ -707,9 +707,9 @@ Link errors / undefined reference
Sometimes dtoc does not find the problem for you, but something is wrong and
you get a link error, e.g.::
:(.u_boot_list_2_udevice_2_spl_test5+0x0): undefined reference to
:(__u_boot_list_2_udevice_2_spl_test5+0x0): undefined reference to
`_u_boot_list_2_driver_2_sandbox_spl_test'
/usr/bin/ld: dts/dt-uclass.o:(.u_boot_list_2_uclass_2_misc+0x8):
/usr/bin/ld: dts/dt-uclass.o:(__u_boot_list_2_uclass_2_misc+0x8):
undefined reference to `_u_boot_list_2_uclass_driver_2_misc'
The first one indicates that the device cannot find its driver. This means that

View file

@ -40,6 +40,8 @@ source "drivers/fastboot/Kconfig"
source "drivers/firmware/Kconfig"
source "drivers/fuzz/Kconfig"
source "drivers/fpga/Kconfig"
source "drivers/gpio/Kconfig"

View file

@ -115,6 +115,7 @@ obj-$(CONFIG_W1) += w1/
obj-$(CONFIG_W1_EEPROM) += w1-eeprom/
obj-$(CONFIG_MACH_PIC32) += ddr/microchip/
obj-$(CONFIG_FUZZ) += fuzz/
obj-$(CONFIG_DM_HWSPINLOCK) += hwspinlock/
obj-$(CONFIG_DM_RNG) += rng/
endif

17
drivers/fuzz/Kconfig Normal file
View file

@ -0,0 +1,17 @@
config DM_FUZZING_ENGINE
bool "Driver support for fuzzing engine devices"
depends on DM
help
Enable driver model for fuzzing engine devices. This interface is
used to get fuzzing inputs from a fuzzing engine.
if DM_FUZZING_ENGINE
config FUZZING_ENGINE_SANDBOX
bool "Sanbox fuzzing engine"
depends on SANDBOX
default y
help
Enable fuzzing engine for sandbox.
endif

8
drivers/fuzz/Makefile Normal file
View file

@ -0,0 +1,8 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2022 Google, Inc.
# Written by Andrew Scull <ascull@google.com>
#
obj-$(CONFIG_DM_FUZZING_ENGINE) += fuzzing_engine-uclass.o
obj-$(CONFIG_FUZZING_ENGINE_SANDBOX) += sandbox_fuzzing_engine.o

View file

@ -0,0 +1,28 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2022 Google, Inc.
* Written by Andrew Scull <ascull@google.com>
*/
#define LOG_CATEGORY UCLASS_FUZZING_ENGINE
#include <common.h>
#include <dm.h>
#include <fuzzing_engine.h>
int dm_fuzzing_engine_get_input(struct udevice *dev,
const uint8_t **data,
size_t *size)
{
const struct dm_fuzzing_engine_ops *ops = device_get_ops(dev);
if (!ops->get_input)
return -ENOSYS;
return ops->get_input(dev, data, size);
}
UCLASS_DRIVER(fuzzing_engine) = {
.name = "fuzzing_engine",
.id = UCLASS_FUZZING_ENGINE,
};

View file

@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2022 Google, Inc.
* Written by Andrew Scull <ascull@google.com>
*/
#include <common.h>
#include <dm.h>
#include <fuzzing_engine.h>
#include <asm/fuzzing_engine.h>
static int get_input(struct udevice *dev,
const uint8_t **data,
size_t *size)
{
return sandbox_fuzzing_engine_get_input(data, size);
}
static const struct dm_fuzzing_engine_ops sandbox_fuzzing_engine_ops = {
.get_input = get_input,
};
static const struct udevice_id sandbox_fuzzing_engine_match[] = {
{
.compatible = "sandbox,fuzzing-engine",
},
{},
};
U_BOOT_DRIVER(sandbox_fuzzing_engine) = {
.name = "sandbox-fuzzing-engine",
.id = UCLASS_FUZZING_ENGINE,
.of_match = sandbox_fuzzing_engine_match,
.ops = &sandbox_fuzzing_engine_ops,
};

View file

@ -114,7 +114,7 @@ static ssize_t sandbox_serial_puts(struct udevice *dev, const char *s,
struct sandbox_serial_priv *priv = dev_get_priv(dev);
ssize_t ret;
if (s[len - 1] == '\n')
if (len && s[len - 1] == '\n')
priv->start_of_line = true;
if (sandbox_serial_enabled) {

View file

@ -56,6 +56,7 @@ enum uclass_id {
UCLASS_ETH, /* Ethernet device */
UCLASS_ETH_PHY, /* Ethernet PHY device */
UCLASS_FIRMWARE, /* Firmware */
UCLASS_FUZZING_ENGINE, /* Fuzzing engine */
UCLASS_FS_FIRMWARE_LOADER, /* Generic loader */
UCLASS_GPIO, /* Bank of general-purpose I/O pins */
UCLASS_HASH, /* Hash device */

51
include/fuzzing_engine.h Normal file
View file

@ -0,0 +1,51 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2022 Google, Inc.
* Written by Andrew Scull <ascull@google.com>
*/
#ifndef __FUZZING_ENGINE_H
#define __FUZZING_ENGINE_H
struct udevice;
/**
* dm_fuzzing_engine_get_input() - get an input from the fuzzing engine device
*
* 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.
*
* @dev: fuzzing engine device
* @data: output pointer to input data
* @size output size of input data
* Return: 0 if OK, -ve on error
*/
int dm_fuzzing_engine_get_input(struct udevice *dev,
const uint8_t **data,
size_t *size);
/**
* struct dm_fuzzing_engine_ops - operations for the fuzzing engine uclass
*
* This contains the functions implemented by a fuzzing engine device.
*/
struct dm_fuzzing_engine_ops {
/**
* @get_input() - get an input
*
* 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.
*
* @get_input.dev: fuzzing engine device
* @get_input.data: output pointer to input data
* @get_input.size output size of input data
* @get_input.Return: 0 if OK, -ve on error
*/
int (*get_input)(struct udevice *dev,
const uint8_t **data,
size_t *size);
};
#endif /* __FUZZING_ENGINE_H */

View file

@ -70,7 +70,7 @@
#define ll_entry_declare(_type, _name, _list) \
_type _u_boot_list_2_##_list##_2_##_name __aligned(4) \
__attribute__((unused)) \
__section(".u_boot_list_2_"#_list"_2_"#_name)
__section("__u_boot_list_2_"#_list"_2_"#_name)
/**
* ll_entry_declare_list() - Declare a list of link-generated array entries
@ -93,7 +93,7 @@
#define ll_entry_declare_list(_type, _name, _list) \
_type _u_boot_list_2_##_list##_2_##_name[] __aligned(4) \
__attribute__((unused)) \
__section(".u_boot_list_2_"#_list"_2_"#_name)
__section("__u_boot_list_2_"#_list"_2_"#_name)
/*
* We need a 0-byte-size type for iterator symbols, and the compiler
@ -110,7 +110,7 @@
* @_list: Name of the list in which this entry is placed
*
* This function returns ``(_type *)`` pointer to the very first entry of a
* linker-generated array placed into subsection of .u_boot_list section
* linker-generated array placed into subsection of __u_boot_list section
* specified by _list argument.
*
* Since this macro defines an array start symbol, its leftmost index
@ -126,7 +126,7 @@
({ \
static char start[0] __aligned(CONFIG_LINKER_LIST_ALIGN) \
__attribute__((unused)) \
__section(".u_boot_list_2_"#_list"_1"); \
__section("__u_boot_list_2_"#_list"_1"); \
(_type *)&start; \
})
@ -137,7 +137,7 @@
* (with underscores instead of dots)
*
* This function returns ``(_type *)`` pointer after the very last entry of
* a linker-generated array placed into subsection of .u_boot_list
* a linker-generated array placed into subsection of __u_boot_list
* section specified by _list argument.
*
* Since this macro defines an array end symbol, its leftmost index
@ -152,7 +152,7 @@
#define ll_entry_end(_type, _list) \
({ \
static char end[0] __aligned(4) __attribute__((unused)) \
__section(".u_boot_list_2_"#_list"_3"); \
__section("__u_boot_list_2_"#_list"_3"); \
(_type *)&end; \
})
/**
@ -161,7 +161,7 @@
* @_list: Name of the list of which the number of elements is computed
*
* This function returns the number of elements of a linker-generated array
* placed into subsection of .u_boot_list section specified by _list
* placed into subsection of __u_boot_list section specified by _list
* argument. The result is of an unsigned int type.
*
* Example:
@ -246,7 +246,7 @@
#define ll_start(_type) \
({ \
static char start[0] __aligned(4) __attribute__((unused)) \
__section(".u_boot_list_1"); \
__section("__u_boot_list_1"); \
(_type *)&start; \
})
@ -269,7 +269,7 @@
#define ll_end(_type) \
({ \
static char end[0] __aligned(4) __attribute__((unused)) \
__section(".u_boot_list_3"); \
__section("__u_boot_list_3"); \
(_type *)&end; \
})

51
include/test/fuzz.h Normal file
View file

@ -0,0 +1,51 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2022 Google, Inc.
* Written by Andrew Scull <ascull@google.com>
*/
#ifndef __TEST_FUZZ_H
#define __TEST_FUZZ_H
#include <linker_lists.h>
#include <linux/types.h>
/**
* struct fuzz_test - Information about a fuzz test
*
* @name: Name of fuzz test
* @func: Function to call to perform fuzz test on an input
* @flags: Flags indicate pre-conditions for fuzz test
*/
struct fuzz_test {
const char *name;
int (*func)(const uint8_t * data, size_t size);
int flags;
};
/**
* FUZZ_TEST() - register a fuzz test
*
* The fuzz test function must return 0 as other values are reserved for future
* use.
*
* @_name: the name of the fuzz test function
* @_flags: an integer field that can be evaluated by the fuzzer
* implementation
*/
#define FUZZ_TEST(_name, _flags) \
ll_entry_declare(struct fuzz_test, _name, fuzz_tests) = { \
.name = #_name, \
.func = _name, \
.flags = _flags, \
}
/** Get the start of the list of fuzz tests */
#define FUZZ_TEST_START() \
ll_entry_start(struct fuzz_test, fuzz_tests)
/** Get the number of elements in the list of fuzz tests */
#define FUZZ_TEST_COUNT() \
ll_entry_count(struct fuzz_test, fuzz_tests)
#endif /* __TEST_FUZZ_H */

View file

@ -16,6 +16,7 @@ obj-$(CONFIG_$(SPL_)CMDLINE) += cmd_ut.o
obj-$(CONFIG_$(SPL_)CMDLINE) += command_ut.o
obj-$(CONFIG_$(SPL_)UT_COMPRESSION) += compression.o
obj-y += dm/
obj-$(CONFIG_FUZZ) += fuzz/
obj-$(CONFIG_$(SPL_)CMDLINE) += print_ut.o
obj-$(CONFIG_$(SPL_)CMDLINE) += str_ut.o
obj-$(CONFIG_UT_TIME) += time_ut.o

8
test/fuzz/Makefile Normal file
View file

@ -0,0 +1,8 @@
# SPDX-License-Identifier: GPL-2.0+
#
# Copyright (c) 2022 Google, Inc.
# Written by Andrew Scull <ascull@google.com>
#
obj-$(CONFIG_$(SPL_)CMDLINE) += cmd_fuzz.o
obj-$(CONFIG_VIRTIO_SANDBOX) += virtio.o

82
test/fuzz/cmd_fuzz.c Normal file
View file

@ -0,0 +1,82 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2022 Google, Inc.
* Written by Andrew Scull <ascull@google.com>
*/
#include <command.h>
#include <common.h>
#include <dm.h>
#include <fuzzing_engine.h>
#include <test/fuzz.h>
static struct fuzz_test *find_fuzz_test(const char *name)
{
struct fuzz_test *fuzzer = FUZZ_TEST_START();
size_t count = FUZZ_TEST_COUNT();
size_t i;
for (i = 0; i < count; ++i) {
if (strcmp(name, fuzzer->name) == 0)
return fuzzer;
++fuzzer;
}
return NULL;
}
static struct udevice *find_fuzzing_engine(void)
{
struct udevice *dev;
if (uclass_first_device(UCLASS_FUZZING_ENGINE, &dev))
return NULL;
return dev;
}
static int do_fuzz(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
struct fuzz_test *fuzzer;
struct udevice *dev;
if (argc != 2)
return CMD_RET_USAGE;
fuzzer = find_fuzz_test(argv[1]);
if (!fuzzer) {
printf("Could not find fuzzer: %s\n", argv[1]);
return 1;
}
dev = find_fuzzing_engine();
if (!dev) {
puts("No fuzzing engine available\n");
return 1;
}
while (1) {
const uint8_t *data;
size_t size;
if (dm_fuzzing_engine_get_input(dev, &data, &size)) {
puts("Fuzzing engine failed\n");
return 1;
}
fuzzer->func(data, size);
}
return 1;
}
#ifdef CONFIG_SYS_LONGHELP
static char fuzz_help_text[] =
"[fuzz-test-name] - execute the named fuzz test\n"
;
#endif /* CONFIG_SYS_LONGHELP */
U_BOOT_CMD(
fuzz, CONFIG_SYS_MAXARGS, 1, do_fuzz,
"fuzz tests", fuzz_help_text
);

72
test/fuzz/virtio.c Normal file
View file

@ -0,0 +1,72 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2022 Google, Inc.
* Written by Andrew Scull <ascull@google.com>
*/
#include <common.h>
#include <dm.h>
#include <virtio.h>
#include <virtio_ring.h>
#include <test/fuzz.h>
static int fuzz_vring(const uint8_t *data, size_t size)
{
struct udevice *bus, *dev;
struct virtio_dev_priv *uc_priv;
struct virtqueue *vq;
struct virtio_sg sg[2];
struct virtio_sg *sgs[2];
unsigned int len;
u8 buffer[2][32];
/* hackily hardcode vring sizes */
size_t num = 4;
size_t desc_size = (sizeof(struct vring_desc) * num);
size_t avail_size = (3 + num) * sizeof(u16);
size_t used_size = (3 * sizeof(u16)) + (sizeof(struct vring_used_elem) * num);
if (size < (desc_size + avail_size + used_size))
return 0;
/* check probe success */
if (uclass_first_device(UCLASS_VIRTIO, &bus) || !bus)
panic("Could not find virtio bus\n");
/* check the child virtio-rng device is bound */
if (device_find_first_child(bus, &dev) || !dev)
panic("Could not find virtio device\n");
/*
* fake the virtio device probe by filling in uc_priv->vdev
* which is used by virtio_find_vqs/virtio_del_vqs.
*/
uc_priv = dev_get_uclass_priv(bus);
uc_priv->vdev = dev;
/* prepare the scatter-gather buffer */
sg[0].addr = buffer[0];
sg[0].length = sizeof(buffer[0]);
sg[1].addr = buffer[1];
sg[1].length = sizeof(buffer[1]);
sgs[0] = &sg[0];
sgs[1] = &sg[1];
if (virtio_find_vqs(dev, 1, &vq))
panic("Could not find vqs\n");
if (virtqueue_add(vq, sgs, 0, 1))
panic("Could not add to virtqueue\n");
/* Simulate device writing to vring */
memcpy(vq->vring.desc, data, desc_size);
memcpy(vq->vring.avail, data + desc_size, avail_size);
memcpy(vq->vring.used, data + desc_size + avail_size, used_size);
/* Make sure there is a response */
if (vq->vring.used->idx == 0)
vq->vring.used->idx = 1;
virtqueue_get_buf(vq, &len);
if (virtio_del_vqs(dev))
panic("Could not delete vqs\n");
return 0;
}
FUZZ_TEST(fuzz_vring, 0);

View file

@ -5,6 +5,7 @@ import pytest
import signal
@pytest.mark.buildconfigspec('cmd_stackprotector_test')
@pytest.mark.notbuildconfigspec('asan')
def test_stackprotector(u_boot_console):
"""Test that the stackprotector function works."""

View file

@ -312,7 +312,7 @@ int main(int argc, char *argv[])
goto out_free_relocs;
}
rel_pfx = is_64 ? ".rela." : ".rel.";
rel_pfx = is_64 ? ".rela" : ".rel";
for (i = 0; i < ehdr_field(e_shnum); i++) {
sh_type = shdr_field(i, sh_type);
@ -321,10 +321,11 @@ int main(int argc, char *argv[])
sh_name = shstr(shdr_field(i, sh_name));
if (strncmp(sh_name, rel_pfx, strlen(rel_pfx))) {
if (strcmp(sh_name, ".rel") && strcmp(sh_name, ".rel.dyn"))
fprintf(stderr, "WARNING: Unexpected reloc section name '%s'\n", sh_name);
fprintf(stderr, "WARNING: Unexpected reloc section name '%s'\n", sh_name);
continue;
}
if (!strcmp(sh_name, ".rel") || !strcmp(sh_name, ".rel.dyn"))
continue;
/*
* Skip reloc sections which either don't correspond to another
@ -334,7 +335,7 @@ int main(int argc, char *argv[])
*/
skip = true;
for (j = 0; j < ehdr_field(e_shnum); j++) {
if (strcmp(&sh_name[strlen(rel_pfx) - 1], shstr(shdr_field(j, sh_name))))
if (strcmp(&sh_name[strlen(rel_pfx)], shstr(shdr_field(j, sh_name))))
continue;
skip = !(shdr_field(j, sh_flags) & SHF_ALLOC);