Now that we have two mechanisms for detecting stack overflows, add a command to intentionally trigger stack frame and stack region overflow to verify their correct operation. Signed-off-by: Ahmad Fatoum <a.fatoum@xxxxxxxxxxxxxx> --- commands/Kconfig | 6 +++++ commands/Makefile | 1 + commands/stacksmash.c | 58 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+) create mode 100644 commands/stacksmash.c diff --git a/commands/Kconfig b/commands/Kconfig index eb95b2a5fbcc..c1bba22443e6 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -2401,6 +2401,12 @@ config CMD_UBSAN This is a test command for the undefined behavior sanitizer. It triggers various undefined behavior, and detect it. +config CMD_STACKSMASH + tristate "stacksmash" + help + This commands trashes the stack to test stackprotector and + guard page. This command does not return. + # end Miscellaneous commands endmenu diff --git a/commands/Makefile b/commands/Makefile index 4b083a852d83..4924755500e3 100644 --- a/commands/Makefile +++ b/commands/Makefile @@ -145,5 +145,6 @@ obj-$(CONFIG_CMD_BTHREAD) += bthread.o obj-$(CONFIG_CMD_UBSAN) += ubsan.o obj-$(CONFIG_CMD_SELFTEST) += selftest.o obj-$(CONFIG_CMD_TUTORIAL) += tutorial.o +obj-$(CONFIG_CMD_STACKSMASH) += stacksmash.o UBSAN_SANITIZE_ubsan.o := y diff --git a/commands/stacksmash.c b/commands/stacksmash.c new file mode 100644 index 000000000000..1e9be0d40e15 --- /dev/null +++ b/commands/stacksmash.c @@ -0,0 +1,58 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <common.h> +#include <command.h> +#include <complete.h> +#include <linux/compiler.h> +#include <string.h> + +static noinline void stack_overflow_frame(void) +{ + volatile int length = 512; + char a[128] = {}; + + /* + * In order to avoid having the compiler optimize away the stack smashing + * we need to do a little something here. + */ + OPTIMIZER_HIDE_VAR(length); + + memset(a, 0xa5, length); + + printf("We have smashed our stack as this should not exceed 128: sizeof(a) = %zu\n", + strlen(a)); +} + +static noinline void stack_overflow_region(u64 i) +{ + volatile char a[1024] = {}; + + if (ctrlc()) + return; + + RELOC_HIDE(&a, 0); + + stack_overflow_region(0); + + printf("%*ph", 1024, a); +} + +static int do_stacksmash(int argc, char *argv[]) +{ + if (argc != 2) + return COMMAND_ERROR_USAGE; + + if (!strcmp(argv[1], "frame")) + stack_overflow_frame(); + else if (!strcmp(argv[1], "region")) + stack_overflow_region(0); + + panic("Stack smashing of %s not caught\n", argv[1]); +} +BAREBOX_CMD_START(stacksmash) + .cmd = do_stacksmash, + BAREBOX_CMD_DESC("Run stack smashing tests") + BAREBOX_CMD_OPTS("[frame | region]") + BAREBOX_CMD_GROUP(CMD_GRP_MISC) + BAREBOX_CMD_COMPLETE(empty_complete) +BAREBOX_CMD_END -- 2.39.2