RE: [RFC PATCH v3 18/22] arm64: Build the kernel with ORC information

Tomohiro Misono (Fujitsu)
2023-02-10T07:53:56Z

Hello,

I see the following build warning after this commit (gcc12):
ld: warning: orphan section `.init.orc_unwind' from `arch/arm64/kernel/pi/kaslr_early.pi.o' being placed in section `.init.orc_unwind'
ld: warning: orphan section `.init.orc_unwind_ip' from `arch/arm64/kernel/pi/kaslr_early.pi.o' being placed in section `.init.orc_unwind_ip'
...

My understanding of the cause is that arch/arm64/kernel/pi has its
own Makefile and adds "init" prefix to sections by objcopy:
https://github.com/madvenka786/linux/blob/orc_v3/arch/arm64/kernel/pi/Makefile#L25

I assume these files are not relevant for livepatch perspective and so it is
safe to exclude these sections by --remove-section or should we care these as well?

Regards,
Tomohiro

> Subject: [RFC PATCH v3 18/22] arm64: Build the kernel with ORC information
>
> From: "Madhavan T. Venkataraman" <madvenka@linux.microsoft.com>
>
> Add code to scripts/Makefile.lib to define objtool options to generate
> ORC data for frame pointer validation.
>
> Define kernel configs:
> - to enable dynamic FRAME_POINTER_VALIDATION
> - to enable the generation of ORC data using objtool
>
> When these configs are enabled, objtool is invoked on relocatable files
> during kernel build with the following command:
>
> objtool --stackval --orc <object-file>
>
> Objtool creates special sections in the object files:
>
> .orc_unwind_ip PC array.
> .orc_unwind ORC structure table.
> .orc_lookup ORC lookup table.
>
> Change arch/arm64/kernel/vmlinux.lds.S to include ORC_UNWIND_TABLE in
> the data section so that the special sections get included there. For
> modules, these sections will be added to the kernel during module load.
>
> In the future, the kernel can use these sections to find the ORC for a
> given instruction address. The unwinder can then compute the FP at an
> instruction address and validate the actual FP with that.
>
> Signed-off-by: Madhavan T. Venkataraman <madvenka@linux.microsoft.com>
> ---
> arch/arm64/Kconfig | 2 ++
> arch/arm64/Kconfig.debug | 32
> ++++++++++++++++++++++++++++++++
> arch/arm64/include/asm/module.h | 12 +++++++++++-
> arch/arm64/kernel/vmlinux.lds.S | 3 +++
> include/linux/objtool.h | 2 ++
> scripts/Makefile | 4 +++-
> scripts/Makefile.lib | 9 +++++++++
> tools/include/linux/objtool.h | 2 ++
> 8 files changed, 64 insertions(+), 2 deletions(-)
>
> diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
> index 505c8a1ccbe0..73c3f30a37c7 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 265c4461031f..a50caabdb18e 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 18734fed3bdd..4362f44aae61 100644
> --- a/arch/arm64/include/asm/module.h
> +++ b/arch/arm64/include/asm/module.h
> @@ -6,6 +6,7 @@
> #define __ASM_MODULE_H
>
> #include <asm-generic/module.h>
> +#include <asm/orc_types.h>
>
> #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 45131e354e27..bf7b55ae10ee 100644
> --- a/arch/arm64/kernel/vmlinux.lds.S
> +++ b/arch/arm64/kernel/vmlinux.lds.S
> @@ -61,6 +61,7 @@
> #define RUNTIME_DISCARD_EXIT
>
> #include <asm-generic/vmlinux.lds.h>
> +#include <asm-generic/orc_lookup.h>
> #include <asm/cache.h>
> #include <asm/kernel-pgtable.h>
> #include <asm/kexec.h>
> @@ -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 dcbd365944f6..c980522190f7 100644
> --- a/include/linux/objtool.h
> +++ b/include/linux/objtool.h
> @@ -31,7 +31,9 @@
>
> #ifdef CONFIG_OBJTOOL
>
> +#ifndef CONFIG_ARM64
> #include <asm/asm.h>
> +#endif
>
> #ifndef __ASSEMBLY__
>
> diff --git a/scripts/Makefile b/scripts/Makefile
> index 1575af84d557..df3e4d90f195 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 3aa384cec76b..d364871a1046 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 dcbd365944f6..c980522190f7 100644
> --- a/tools/include/linux/objtool.h
> +++ b/tools/include/linux/objtool.h
> @@ -31,7 +31,9 @@
>
> #ifdef CONFIG_OBJTOOL
>
> +#ifndef CONFIG_ARM64
> #include <asm/asm.h>
> +#endif
>
> #ifndef __ASSEMBLY__
>
> --
> 2.25.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel