diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 505c8a1ccbe0cd..73c3f30a37c776 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -230,6 +230,8 @@ config ARM64 select TRACE_IRQFLAGS_SUPPORT select TRACE_IRQFLAGS_NMI_SUPPORT select HAVE_SOFTIRQ_ON_OWN_STACK + select HAVE_STACK_VALIDATION if FRAME_POINTER_VALIDATION + select STACK_VALIDATION if HAVE_STACK_VALIDATION help ARM 64-bit (AArch64) Linux support. diff --git a/arch/arm64/Kconfig.debug b/arch/arm64/Kconfig.debug index 265c4461031f4d..a50caabdb18ec8 100644 --- a/arch/arm64/Kconfig.debug +++ b/arch/arm64/Kconfig.debug @@ -20,4 +20,36 @@ config ARM64_RELOC_TEST depends on m tristate "Relocation testing module" +config UNWINDER_ORC + bool "ORC unwinder" + depends on FRAME_POINTER_VALIDATION + select HAVE_MOD_ARCH_SPECIFIC + select OBJTOOL + help + This option enables ORC (Oops Rewind Capability) for ARM64. This + allows the unwinder to look up ORC data for an instruction address + and compute the frame pointer at that address. The computed frame + pointer is used to validate the actual frame pointer. + +config UNWINDER_FRAME_POINTER + bool "Frame pointer unwinder" + depends on FRAME_POINTER_VALIDATION + select FRAME_POINTER + help + ARM64 already uses the frame pointer for unwinding kernel stack + traces. We need to enable this config to enable STACK_VALIDATION. + STACK_VALIDATION is needed to get objtool to do static analysis + of kernel code. + +config FRAME_POINTER_VALIDATION + bool "Dynamic Frame pointer validation" + select UNWINDER_FRAME_POINTER + select UNWINDER_ORC + help + This invokes objtool on every object file causing it to + generate ORC data for the object file. ORC data is in a custom + data format which is a simplified version of the DWARF + Call Frame Information standard. See UNWINDER_ORC for more + details. + source "drivers/hwtracing/coresight/Kconfig" diff --git a/arch/arm64/include/asm/module.h b/arch/arm64/include/asm/module.h index 18734fed3bdd76..4362f44aae61ee 100644 --- a/arch/arm64/include/asm/module.h +++ b/arch/arm64/include/asm/module.h @@ -6,6 +6,7 @@ #define __ASM_MODULE_H #include +#include #ifdef CONFIG_ARM64_MODULE_PLTS struct mod_plt_sec { @@ -13,15 +14,24 @@ struct mod_plt_sec { int plt_num_entries; int plt_max_entries; }; +#endif +#ifdef CONFIG_HAVE_MOD_ARCH_SPECIFIC struct mod_arch_specific { +#ifdef CONFIG_ARM64_MODULE_PLTS struct mod_plt_sec core; struct mod_plt_sec init; /* for CONFIG_DYNAMIC_FTRACE */ struct plt_entry *ftrace_trampolines; -}; #endif +#ifdef CONFIG_UNWINDER_ORC + unsigned int num_orcs; + int *orc_unwind_ip; + struct orc_entry *orc_unwind; +#endif +}; +#endif /* CONFIG_HAVE_MOD_ARCH_SPECIFIC */ u64 module_emit_plt_entry(struct module *mod, Elf64_Shdr *sechdrs, void *loc, const Elf64_Rela *rela, diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S index 45131e354e27f1..bf7b55ae10eef1 100644 --- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S @@ -61,6 +61,7 @@ #define RUNTIME_DISCARD_EXIT #include +#include #include #include #include @@ -294,6 +295,8 @@ SECTIONS __mmuoff_data_end = .; } + ORC_UNWIND_TABLE + PECOFF_EDATA_PADDING __pecoff_data_rawsize = ABSOLUTE(. - __initdata_begin); _edata = .; diff --git a/include/linux/objtool.h b/include/linux/objtool.h index dcbd365944f696..c980522190f71c 100644 --- a/include/linux/objtool.h +++ b/include/linux/objtool.h @@ -31,7 +31,9 @@ #ifdef CONFIG_OBJTOOL +#ifndef CONFIG_ARM64 #include +#endif #ifndef __ASSEMBLY__ diff --git a/scripts/Makefile b/scripts/Makefile index 1575af84d557bd..df3e4d90f195e6 100644 --- a/scripts/Makefile +++ b/scripts/Makefile @@ -23,8 +23,10 @@ HOSTLDLIBS_sign-file = $(shell $(HOSTPKG_CONFIG) --libs libcrypto 2> /dev/null | ifdef CONFIG_UNWINDER_ORC ifeq ($(ARCH),x86_64) ARCH := x86 -endif HOSTCFLAGS_sorttable.o += -I$(srctree)/tools/arch/x86/include +else +HOSTCFLAGS_sorttable.o += -I$(srctree)/tools/arch/$(ARCH)/include +endif HOSTCFLAGS_sorttable.o += -DUNWINDER_ORC_ENABLED endif diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 3aa384cec76b8b..d364871a1046b2 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -252,6 +252,13 @@ ifdef CONFIG_OBJTOOL objtool := $(objtree)/tools/objtool/objtool +ifdef CONFIG_FRAME_POINTER_VALIDATION + +objtool-args-$(CONFIG_STACK_VALIDATION) += --stackval +objtool-args-$(CONFIG_UNWINDER_ORC) += --orc + +else + objtool-args-$(CONFIG_HAVE_JUMP_LABEL_HACK) += --hacks=jump_label objtool-args-$(CONFIG_HAVE_NOINSTR_HACK) += --hacks=noinstr objtool-args-$(CONFIG_X86_KERNEL_IBT) += --ibt @@ -265,6 +272,8 @@ objtool-args-$(CONFIG_HAVE_STATIC_CALL_INLINE) += --static-call objtool-args-$(CONFIG_HAVE_UACCESS_VALIDATION) += --uaccess objtool-args-$(CONFIG_GCOV_KERNEL) += --no-unreachable +endif + objtool-args = $(objtool-args-y) \ $(if $(delay-objtool), --link) \ $(if $(part-of-module), --module) diff --git a/tools/include/linux/objtool.h b/tools/include/linux/objtool.h index dcbd365944f696..c980522190f71c 100644 --- a/tools/include/linux/objtool.h +++ b/tools/include/linux/objtool.h @@ -31,7 +31,9 @@ #ifdef CONFIG_OBJTOOL +#ifndef CONFIG_ARM64 #include +#endif #ifndef __ASSEMBLY__