Re: [RFC PATCH v5 2/2] arm64: Create a list of SYM_CODE functions, check return PC against list
From: Suraj Jitindar Singh <sjitindarsingh@gmail.com>
Date: 2021-06-16 01:52:06
Also in:
linux-arm-kernel, lkml
On Wed, 2021-05-26 at 16:49 -0500, madvenka@linux.microsoft.com wrote:
From: "Madhavan T. Venkataraman" <redacted> The unwinder should check if the return PC falls in any function that is considered unreliable from an unwinding perspective. If it does, mark the stack trace unreliable.
[snip] Correct me if I'm wrong, but do you not need to move the final frame check to before the unwinder_is_unreliable() call? Userland threads which have ret_from_fork as the last entry on the stack will always be marked unreliable as they will always have a SYM_CODE entry on their stack (the ret_from_fork). Also given that this means the last frame has been reached and as such there's no more unwinding to do, I don't think we care if the last pc is a code address. - Suraj
quoted hunk ↗ jump to hunk
*@@ -133,7 +236,20 @@ int notrace unwind_frame(struct task_struct*tsk, struct stackframe *frame) * - Foreign code (e.g. EFI runtime services) * - Procedure Linkage Table (PLT) entries and veneer functions */ - if (!__kernel_text_address(frame->pc)) + if (!__kernel_text_address(frame->pc)) { + frame->reliable = false; + return 0; + } + + /* + * If the final frame has been reached, there is no more unwinding + * to do. There is no need to check if the return PC is considered + * unreliable by the unwinder. + */ + if (!frame->fp) + return 0;
if (frame->fp == (unsigned long)task_pt_regs(tsk)->stackframe) return -ENOENT;
quoted hunk ↗ jump to hunk
+ + if (unwinder_is_unreliable(frame->pc)) frame->reliable = false; return 0;diff --git a/arch/arm64/kernel/vmlinux.lds.Sb/arch/arm64/kernel/vmlinux.lds.S index 7eea7888bb02..32e8d57397a1 100644--- a/arch/arm64/kernel/vmlinux.lds.S +++ b/arch/arm64/kernel/vmlinux.lds.S@@ -103,6 +103,12 @@ jiffies = jiffies_64; #define TRAMP_TEXT #endif +#define SYM_CODE_FUNCTIONS \ + . = ALIGN(16); \ + __sym_code_functions_start = .; \ + KEEP(*(sym_code_functions)) \ + __sym_code_functions_end = .; + /* * The size of the PE/COFF section that covers the kernel image,which * runs from _stext to _edata, must be a round multiple of the PE/COFF@@ -218,6 +224,7 @@ SECTIONS CON_INITCALL INIT_RAM_FS *(.init.altinstructions .init.bss) /* from theEFI stub */ + SYM_CODE_FUNCTIONS } .exit.data : { EXIT_DATA