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

Madhavan T. Venkataraman madvenka at linux.microsoft.com
Fri Feb 10 20:34:03 PST 2023


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 at 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 at 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 at lists.infradead.org
>> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel



More information about the linux-arm-kernel mailing list