diff --git a/.azure-pipelines.yml b/.azure-pipelines.yml index ad540ea635..915d5115b1 100644 --- a/.azure-pipelines.yml +++ b/.azure-pipelines.yml @@ -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: diff --git a/Kconfig b/Kconfig index 429b5f9a70..991b260182 100644 --- a/Kconfig +++ b/Kconfig @@ -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) diff --git a/arch/Kconfig b/arch/Kconfig index b396263e3b..eab89f255b 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -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 diff --git a/arch/arc/cpu/u-boot.lds b/arch/arc/cpu/u-boot.lds index e12145c768..9f2973da65 100644 --- a/arch/arc/cpu/u-boot.lds +++ b/arch/arc/cpu/u-boot.lds @@ -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); diff --git a/arch/arm/config.mk b/arch/arm/config.mk index b107b1af27..b3548ce243 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -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 diff --git a/arch/arm/cpu/arm926ejs/sunxi/u-boot-spl.lds b/arch/arm/cpu/arm926ejs/sunxi/u-boot-spl.lds index 9a000ac5d3..c108736811 100644 --- a/arch/arm/cpu/arm926ejs/sunxi/u-boot-spl.lds +++ b/arch/arm/cpu/arm926ejs/sunxi/u-boot-spl.lds @@ -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); diff --git a/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds b/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds index 942c29fc95..306a4ddf3c 100644 --- a/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds +++ b/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds @@ -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); diff --git a/arch/arm/cpu/armv8/u-boot-spl.lds b/arch/arm/cpu/armv8/u-boot-spl.lds index 730eb93dbc..d02b788e60 100644 --- a/arch/arm/cpu/armv8/u-boot-spl.lds +++ b/arch/arm/cpu/armv8/u-boot-spl.lds @@ -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 : { diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds index 2554980595..8fe4682dd2 100644 --- a/arch/arm/cpu/armv8/u-boot.lds +++ b/arch/arm/cpu/armv8/u-boot.lds @@ -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); diff --git a/arch/arm/cpu/u-boot-spl.lds b/arch/arm/cpu/u-boot-spl.lds index 97899a567f..fb2189d50d 100644 --- a/arch/arm/cpu/u-boot-spl.lds +++ b/arch/arm/cpu/u-boot-spl.lds @@ -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); diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds index 0eb164d2e6..f25f72b2e0 100644 --- a/arch/arm/cpu/u-boot.lds +++ b/arch/arm/cpu/u-boot.lds @@ -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); diff --git a/arch/arm/mach-at91/arm926ejs/u-boot-spl.lds b/arch/arm/mach-at91/arm926ejs/u-boot-spl.lds index 74f6355229..1a8bf94dee 100644 --- a/arch/arm/mach-at91/arm926ejs/u-boot-spl.lds +++ b/arch/arm/mach-at91/arm926ejs/u-boot-spl.lds @@ -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 = .; diff --git a/arch/arm/mach-at91/armv7/u-boot-spl.lds b/arch/arm/mach-at91/armv7/u-boot-spl.lds index 950ea55d7c..6ca725fc4c 100644 --- a/arch/arm/mach-at91/armv7/u-boot-spl.lds +++ b/arch/arm/mach-at91/armv7/u-boot-spl.lds @@ -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 = .; diff --git a/arch/arm/mach-omap2/u-boot-spl.lds b/arch/arm/mach-omap2/u-boot-spl.lds index 88d81f9b98..1d6e5d45b4 100644 --- a/arch/arm/mach-omap2/u-boot-spl.lds +++ b/arch/arm/mach-omap2/u-boot-spl.lds @@ -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); diff --git a/arch/arm/mach-orion5x/u-boot-spl.lds b/arch/arm/mach-orion5x/u-boot-spl.lds index a537fe0295..154bb12060 100644 --- a/arch/arm/mach-orion5x/u-boot-spl.lds +++ b/arch/arm/mach-orion5x/u-boot-spl.lds @@ -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); diff --git a/arch/arm/mach-rockchip/u-boot-tpl-v8.lds b/arch/arm/mach-rockchip/u-boot-tpl-v8.lds index 9869972e22..74618eba59 100644 --- a/arch/arm/mach-rockchip/u-boot-tpl-v8.lds +++ b/arch/arm/mach-rockchip/u-boot-tpl-v8.lds @@ -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 : { diff --git a/arch/arm/mach-zynq/u-boot-spl.lds b/arch/arm/mach-zynq/u-boot-spl.lds index 106d2e390b..8c18d3f91f 100644 --- a/arch/arm/mach-zynq/u-boot-spl.lds +++ b/arch/arm/mach-zynq/u-boot-spl.lds @@ -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); diff --git a/arch/arm/mach-zynq/u-boot.lds b/arch/arm/mach-zynq/u-boot.lds index 91c32e89e8..a5169fd915 100644 --- a/arch/arm/mach-zynq/u-boot.lds +++ b/arch/arm/mach-zynq/u-boot.lds @@ -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); diff --git a/arch/m68k/cpu/u-boot.lds b/arch/m68k/cpu/u-boot.lds index affb2d9374..133f79150b 100644 --- a/arch/m68k/cpu/u-boot.lds +++ b/arch/m68k/cpu/u-boot.lds @@ -60,8 +60,8 @@ SECTIONS . = .; . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); + __u_boot_list : { + KEEP(*(SORT(__u_boot_list*))); } . = .; diff --git a/arch/microblaze/cpu/u-boot-spl.lds b/arch/microblaze/cpu/u-boot-spl.lds index 7883a64b15..4ac5a21524 100644 --- a/arch/microblaze/cpu/u-boot-spl.lds +++ b/arch/microblaze/cpu/u-boot-spl.lds @@ -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 = . ; diff --git a/arch/microblaze/cpu/u-boot.lds b/arch/microblaze/cpu/u-boot.lds index 2b316cc7f5..8bd515b099 100644 --- a/arch/microblaze/cpu/u-boot.lds +++ b/arch/microblaze/cpu/u-boot.lds @@ -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 = . ; diff --git a/arch/mips/config.mk b/arch/mips/config.mk index faf4129ac1..04f3627805 100644 --- a/arch/mips/config.mk +++ b/arch/mips/config.mk @@ -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 diff --git a/arch/mips/cpu/u-boot-spl.lds b/arch/mips/cpu/u-boot-spl.lds index 28ea4f2a48..194398be85 100644 --- a/arch/mips/cpu/u-boot-spl.lds +++ b/arch/mips/cpu/u-boot-spl.lds @@ -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 diff --git a/arch/mips/cpu/u-boot.lds b/arch/mips/cpu/u-boot.lds index 86496737d3..9a4ebcd151 100644 --- a/arch/mips/cpu/u-boot.lds +++ b/arch/mips/cpu/u-boot.lds @@ -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); diff --git a/arch/nios2/cpu/u-boot.lds b/arch/nios2/cpu/u-boot.lds index cbf54b4610..5b9e27d940 100644 --- a/arch/nios2/cpu/u-boot.lds +++ b/arch/nios2/cpu/u-boot.lds @@ -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) diff --git a/arch/powerpc/cpu/mpc83xx/u-boot.lds b/arch/powerpc/cpu/mpc83xx/u-boot.lds index d10f528da4..1a1e537b2a 100644 --- a/arch/powerpc/cpu/mpc83xx/u-boot.lds +++ b/arch/powerpc/cpu/mpc83xx/u-boot.lds @@ -42,8 +42,8 @@ SECTIONS . = .; . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); + __u_boot_list : { + KEEP(*(SORT(__u_boot_list*))); } diff --git a/arch/powerpc/cpu/mpc85xx/u-boot-spl.lds b/arch/powerpc/cpu/mpc85xx/u-boot-spl.lds index 1b4d1e05a4..06a70ff2af 100644 --- a/arch/powerpc/cpu/mpc85xx/u-boot-spl.lds +++ b/arch/powerpc/cpu/mpc85xx/u-boot-spl.lds @@ -50,8 +50,8 @@ SECTIONS _edata = .; . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); + __u_boot_list : { + KEEP(*(SORT(__u_boot_list*))); } . = .; diff --git a/arch/powerpc/cpu/mpc85xx/u-boot.lds b/arch/powerpc/cpu/mpc85xx/u-boot.lds index e1bbee43bc..8bbe319b3e 100644 --- a/arch/powerpc/cpu/mpc85xx/u-boot.lds +++ b/arch/powerpc/cpu/mpc85xx/u-boot.lds @@ -67,8 +67,8 @@ SECTIONS . = .; . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); + __u_boot_list : { + KEEP(*(SORT(__u_boot_list*))); } . = .; diff --git a/arch/riscv/cpu/u-boot-spl.lds b/arch/riscv/cpu/u-boot-spl.lds index d0495ce248..993536302a 100644 --- a/arch/riscv/cpu/u-boot-spl.lds +++ b/arch/riscv/cpu/u-boot-spl.lds @@ -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); diff --git a/arch/riscv/cpu/u-boot.lds b/arch/riscv/cpu/u-boot.lds index c00d17c736..1c937aebee 100644 --- a/arch/riscv/cpu/u-boot.lds +++ b/arch/riscv/cpu/u-boot.lds @@ -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); diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk index 02a3ba0c0e..3e2c7f9ebe 100644 --- a/arch/sandbox/config.mk +++ b/arch/sandbox/config.mk @@ -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)) diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index 5ea5417917..3b230606a9 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -26,7 +27,9 @@ #include #include +#include #include +#include #include #include #include @@ -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 diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 0f5a87309d..90a84e93c7 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -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; diff --git a/arch/sandbox/cpu/u-boot-spl.lds b/arch/sandbox/cpu/u-boot-spl.lds index 206e265e74..ef885fd0cb 100644 --- a/arch/sandbox/cpu/u-boot-spl.lds +++ b/arch/sandbox/cpu/u-boot-spl.lds @@ -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) } } diff --git a/arch/sandbox/cpu/u-boot.lds b/arch/sandbox/cpu/u-boot.lds index 92e834a8d2..ba8dee50c7 100644 --- a/arch/sandbox/cpu/u-boot.lds +++ b/arch/sandbox/cpu/u-boot.lds @@ -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 : diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index e068d0c8c5..0194b9b30e 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -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>; diff --git a/arch/sandbox/include/asm/fuzzing_engine.h b/arch/sandbox/include/asm/fuzzing_engine.h new file mode 100644 index 0000000000..cf6396363b --- /dev/null +++ b/arch/sandbox/include/asm/fuzzing_engine.h @@ -0,0 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2022 Google, Inc. + * Written by Andrew Scull + */ + +#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 */ diff --git a/arch/sandbox/include/asm/getopt.h b/arch/sandbox/include/asm/getopt.h index d2145ad6e2..df30572d6c 100644 --- a/arch/sandbox/include/asm/getopt.h +++ b/arch/sandbox/include/asm/getopt.h @@ -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 diff --git a/arch/sandbox/include/asm/main.h b/arch/sandbox/include/asm/main.h new file mode 100644 index 0000000000..7a2f0d3a8d --- /dev/null +++ b/arch/sandbox/include/asm/main.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2022 Google, Inc. + * Written by Andrew Scull + */ + +#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 */ diff --git a/arch/sandbox/include/asm/sections.h b/arch/sandbox/include/asm/sections.h index f4351ae7db..88837bb35c 100644 --- a/arch/sandbox/include/asm/sections.h +++ b/arch/sandbox/include/asm/sections.h @@ -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; } diff --git a/arch/sandbox/lib/sections.c b/arch/sandbox/lib/sections.c index 2559eeea38..2f2f3fbfdb 100644 --- a/arch/sandbox/lib/sections.c +++ b/arch/sandbox/lib/sections.c @@ -5,9 +5,9 @@ */ #include -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"); diff --git a/arch/sh/cpu/u-boot.lds b/arch/sh/cpu/u-boot.lds index 4cc97737f1..ff80ce78f3 100644 --- a/arch/sh/cpu/u-boot.lds +++ b/arch/sh/cpu/u-boot.lds @@ -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 = .); diff --git a/arch/x86/cpu/u-boot-64.lds b/arch/x86/cpu/u-boot-64.lds index 92a30c2a38..53c56043a9 100644 --- a/arch/x86/cpu/u-boot-64.lds +++ b/arch/x86/cpu/u-boot-64.lds @@ -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); diff --git a/arch/x86/cpu/u-boot-spl.lds b/arch/x86/cpu/u-boot-spl.lds index 346f60bdac..a0a2a06a18 100644 --- a/arch/x86/cpu/u-boot-spl.lds +++ b/arch/x86/cpu/u-boot-spl.lds @@ -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); diff --git a/arch/x86/cpu/u-boot.lds b/arch/x86/cpu/u-boot.lds index 22fde01e74..7c87209834 100644 --- a/arch/x86/cpu/u-boot.lds +++ b/arch/x86/cpu/u-boot.lds @@ -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); diff --git a/arch/x86/lib/elf_ia32_efi.lds b/arch/x86/lib/elf_ia32_efi.lds index aad61e7f81..6d89c1fbd5 100644 --- a/arch/x86/lib/elf_ia32_efi.lds +++ b/arch/x86/lib/elf_ia32_efi.lds @@ -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! */ diff --git a/arch/x86/lib/elf_x86_64_efi.lds b/arch/x86/lib/elf_x86_64_efi.lds index 75727400aa..ada024c05c 100644 --- a/arch/x86/lib/elf_x86_64_efi.lds +++ b/arch/x86/lib/elf_x86_64_efi.lds @@ -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); diff --git a/arch/xtensa/cpu/u-boot.lds b/arch/xtensa/cpu/u-boot.lds index 493f3fdb99..84ba32c044 100644 --- a/arch/xtensa/cpu/u-boot.lds +++ b/arch/xtensa/cpu/u-boot.lds @@ -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 = .; diff --git a/arch/xtensa/include/asm/ldscript.h b/arch/xtensa/include/asm/ldscript.h index 08f5d0135e..78a0b230bd 100644 --- a/arch/xtensa/include/asm/ldscript.h +++ b/arch/xtensa/include/asm/ldscript.h @@ -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_) \ diff --git a/board/compulab/cm_t335/u-boot.lds b/board/compulab/cm_t335/u-boot.lds index b00e466d58..4993880461 100644 --- a/board/compulab/cm_t335/u-boot.lds +++ b/board/compulab/cm_t335/u-boot.lds @@ -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); diff --git a/board/cssi/MCR3000/u-boot.lds b/board/cssi/MCR3000/u-boot.lds index 70aef3241c..24b535e724 100644 --- a/board/cssi/MCR3000/u-boot.lds +++ b/board/cssi/MCR3000/u-boot.lds @@ -59,8 +59,8 @@ SECTIONS . = .; . = ALIGN(4); - .u_boot_list : { - KEEP(*(SORT(.u_boot_list*))); + __u_boot_list : { + KEEP(*(SORT(__u_boot_list*))); } . = .; diff --git a/board/davinci/da8xxevm/u-boot-spl-da850evm.lds b/board/davinci/da8xxevm/u-boot-spl-da850evm.lds index f6b9de2908..7e0f09f3b5 100644 --- a/board/davinci/da8xxevm/u-boot-spl-da850evm.lds +++ b/board/davinci/da8xxevm/u-boot-spl-da850evm.lds @@ -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 : { diff --git a/board/qualcomm/dragonboard820c/u-boot.lds b/board/qualcomm/dragonboard820c/u-boot.lds index dcf8256cec..5251b59fbe 100644 --- a/board/qualcomm/dragonboard820c/u-boot.lds +++ b/board/qualcomm/dragonboard820c/u-boot.lds @@ -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); diff --git a/board/samsung/common/exynos-uboot-spl.lds b/board/samsung/common/exynos-uboot-spl.lds index 5b32f7feb8..73cd97a1b1 100644 --- a/board/samsung/common/exynos-uboot-spl.lds +++ b/board/samsung/common/exynos-uboot-spl.lds @@ -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); diff --git a/board/synopsys/iot_devkit/u-boot.lds b/board/synopsys/iot_devkit/u-boot.lds index 5aff100315..e82e4987f6 100644 --- a/board/synopsys/iot_devkit/u-boot.lds +++ b/board/synopsys/iot_devkit/u-boot.lds @@ -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); diff --git a/board/ti/am335x/u-boot.lds b/board/ti/am335x/u-boot.lds index 03c1d5f73b..087dee8bb2 100644 --- a/board/ti/am335x/u-boot.lds +++ b/board/ti/am335x/u-boot.lds @@ -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); diff --git a/board/vscom/baltos/u-boot.lds b/board/vscom/baltos/u-boot.lds index 315ba5b99a..cb2ee67697 100644 --- a/board/vscom/baltos/u-boot.lds +++ b/board/vscom/baltos/u-boot.lds @@ -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); diff --git a/doc/api/linker_lists.rst b/doc/api/linker_lists.rst index 7063fdc831..3cd447f187 100644 --- a/doc/api/linker_lists.rst +++ b/doc/api/linker_lists.rst @@ -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 diff --git a/doc/develop/commands.rst b/doc/develop/commands.rst index c72d1b0aaa..ede880d248 100644 --- a/doc/develop/commands.rst +++ b/doc/develop/commands.rst @@ -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 diff --git a/doc/develop/driver-model/of-plat.rst b/doc/develop/driver-model/of-plat.rst index 237af38ad4..b454f7be85 100644 --- a/doc/develop/driver-model/of-plat.rst +++ b/doc/develop/driver-model/of-plat.rst @@ -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 diff --git a/drivers/Kconfig b/drivers/Kconfig index b26ca8cf70..8b6fead351 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -40,6 +40,8 @@ source "drivers/fastboot/Kconfig" source "drivers/firmware/Kconfig" +source "drivers/fuzz/Kconfig" + source "drivers/fpga/Kconfig" source "drivers/gpio/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 67c8af7442..d63fd1c04d 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -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 diff --git a/drivers/fuzz/Kconfig b/drivers/fuzz/Kconfig new file mode 100644 index 0000000000..6311385222 --- /dev/null +++ b/drivers/fuzz/Kconfig @@ -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 diff --git a/drivers/fuzz/Makefile b/drivers/fuzz/Makefile new file mode 100644 index 0000000000..073743ba94 --- /dev/null +++ b/drivers/fuzz/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) 2022 Google, Inc. +# Written by Andrew Scull +# + +obj-$(CONFIG_DM_FUZZING_ENGINE) += fuzzing_engine-uclass.o +obj-$(CONFIG_FUZZING_ENGINE_SANDBOX) += sandbox_fuzzing_engine.o diff --git a/drivers/fuzz/fuzzing_engine-uclass.c b/drivers/fuzz/fuzzing_engine-uclass.c new file mode 100644 index 0000000000..b16f1c4cfb --- /dev/null +++ b/drivers/fuzz/fuzzing_engine-uclass.c @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2022 Google, Inc. + * Written by Andrew Scull + */ + +#define LOG_CATEGORY UCLASS_FUZZING_ENGINE + +#include +#include +#include + +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, +}; diff --git a/drivers/fuzz/sandbox_fuzzing_engine.c b/drivers/fuzz/sandbox_fuzzing_engine.c new file mode 100644 index 0000000000..ebb938e5ba --- /dev/null +++ b/drivers/fuzz/sandbox_fuzzing_engine.c @@ -0,0 +1,35 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2022 Google, Inc. + * Written by Andrew Scull + */ + +#include +#include +#include +#include + +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, +}; diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c index e726e19c46..13b54921c4 100644 --- a/drivers/serial/sandbox.c +++ b/drivers/serial/sandbox.c @@ -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) { diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h index 3ba69ad9a0..a432e43871 100644 --- a/include/dm/uclass-id.h +++ b/include/dm/uclass-id.h @@ -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 */ diff --git a/include/fuzzing_engine.h b/include/fuzzing_engine.h new file mode 100644 index 0000000000..357346e93d --- /dev/null +++ b/include/fuzzing_engine.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2022 Google, Inc. + * Written by Andrew Scull + */ + +#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 */ diff --git a/include/linker_lists.h b/include/linker_lists.h index 0575164ce4..d3da9d44e8 100644 --- a/include/linker_lists.h +++ b/include/linker_lists.h @@ -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; \ }) diff --git a/include/test/fuzz.h b/include/test/fuzz.h new file mode 100644 index 0000000000..d4c57540eb --- /dev/null +++ b/include/test/fuzz.h @@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2022 Google, Inc. + * Written by Andrew Scull + */ + +#ifndef __TEST_FUZZ_H +#define __TEST_FUZZ_H + +#include +#include + +/** + * 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 */ diff --git a/test/Makefile b/test/Makefile index abd605a435..1dfd567744 100644 --- a/test/Makefile +++ b/test/Makefile @@ -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 diff --git a/test/fuzz/Makefile b/test/fuzz/Makefile new file mode 100644 index 0000000000..663b79ce80 --- /dev/null +++ b/test/fuzz/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) 2022 Google, Inc. +# Written by Andrew Scull +# + +obj-$(CONFIG_$(SPL_)CMDLINE) += cmd_fuzz.o +obj-$(CONFIG_VIRTIO_SANDBOX) += virtio.o diff --git a/test/fuzz/cmd_fuzz.c b/test/fuzz/cmd_fuzz.c new file mode 100644 index 0000000000..0cc01dc199 --- /dev/null +++ b/test/fuzz/cmd_fuzz.c @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2022 Google, Inc. + * Written by Andrew Scull + */ + +#include +#include +#include +#include +#include + +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 +); diff --git a/test/fuzz/virtio.c b/test/fuzz/virtio.c new file mode 100644 index 0000000000..e5363d5638 --- /dev/null +++ b/test/fuzz/virtio.c @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (c) 2022 Google, Inc. + * Written by Andrew Scull + */ + +#include +#include +#include +#include +#include + +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); diff --git a/test/py/tests/test_stackprotector.py b/test/py/tests/test_stackprotector.py index b009437e5e..b87392c54f 100644 --- a/test/py/tests/test_stackprotector.py +++ b/test/py/tests/test_stackprotector.py @@ -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.""" diff --git a/tools/mips-relocs.c b/tools/mips-relocs.c index 625258085b..5db610f5c7 100644 --- a/tools/mips-relocs.c +++ b/tools/mips-relocs.c @@ -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);