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

Madhavan T. Venkataraman
2023-02-11T04:34:13Z

I will analyze this and respond.

Thanks for mentioning this.

Madhavan

On 2/10/23 01:52, Tomohiro Misono (Fujitsu) wrote:
> 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
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel