Re: [PATCH v14 18/19] unwind_user/sframe/x86: Enable sframe unwinding on x86
Jens Remus <[email protected]> Mon, 18 May 2026 17:33:45 +0200
| Newsgroups | dev.linux.lists.sashiko,org.kernel.vger.bpf |
|---|---|
| Organization | IBM Deutschland Research & Development GmbH |
| Message-ID | <[email protected]> |
On 5/5/2026 9:07 PM, [email protected] wrote: > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: > - [High] SFrame unwinding uses incorrect DWARF register mappings for 32-bit (compat) user processes on x86_64. > -- > > commit 014ce7a38c83420c1017dd7293ec85cc9b4e45d6 > Author: Josh Poimboeuf <[email protected]> > unwind_user/sframe/x86: Enable sframe unwinding on x86 > > This commit enables SFrame V3 unwinding on x86, which requires binutils 2.46. > It introduces DWARF register mappings and sets the SFrame register constants. > >> diff --git a/arch/x86/include/asm/unwind_user.h b/arch/x86/include/asm/unwind_user.h >> index f38f7c5ff1de1..b80f0ec0f7a74 100644 >> --- a/arch/x86/include/asm/unwind_user.h >> +++ b/arch/x86/include/asm/unwind_user.h >> @@ -15,6 +15,39 @@ static inline int unwind_user_word_size(struct pt_regs *regs) >> return user_64bit_mode(regs) ? 8 : 4; >> } >> >> +static inline int unwind_user_get_reg(unsigned long *val, unsigned int regnum) >> +{ >> +#ifdef CONFIG_X86_64 >> + const struct pt_regs *regs = task_pt_regs(current); >> + SFrame is currently only supported on x86-64 (no 32-bit compat): if (!user_64bit_mode(regs)) return -EINVAL; >> + switch (regnum) { >> + /* DWARF register numbers 0..15 */ >> + case 0: *val = regs->ax; break; >> + case 1: *val = regs->dx; break; >> + case 2: *val = regs->cx; break; >> + case 3: *val = regs->bx; break; >> + case 4: *val = regs->si; break; >> + case 5: *val = regs->di; break; >> + case 6: *val = regs->bp; break; >> + case 7: *val = regs->sp; break; > > Does this code handle 32-bit (compat) user processes correctly? > > 32-bit (i386) processes use a different DWARF mapping where ESP is 4 and > EBP is 5, but this code unconditionally uses the x86_64 DWARF register > mapping (where register 4 is RSI and 7 is RSP). > > When an i386 application uses an SFrame V3 flexible FDE, the DWARF register > number is explicitly encoded in the FRE data words. The generic unwinder > sframe_init_cfa_rule_data() compares the register against the hardcoded > SFRAME_REG_SP (which is 7 on x86_64). > > Since an i386 SFrame specifies 4 for SP, the check would fail and fall > back to UNWIND_USER_CFA_RULE_REG_OFFSET with regnum = 4. Then > unwind_user_next_common() would call unwind_user_get_reg(&cfa, 4), which > would return regs->si instead of regs->sp. > > Could this break unwinding for 32-bit tasks by using the wrong registers > (e.g., RSI acting as the stack pointer), leading to corrupted stack traces? > Would the unwinder need to be explicitly disabled for compat tasks or > dynamically adjust the DWARF mappings using user_64bit_mode(regs)? > Regards, Jens -- Jens Remus Linux on Z Development (D3303) [email protected] / [email protected] IBM Deutschland Research & Development GmbH; Vorsitzender des Aufsichtsrats: Wolfgang Wendt; Geschäftsführung: David Faller; Sitz der Gesellschaft: Ehningen; Registergericht: Amtsgericht Stuttgart, HRB 243294 IBM Data Privacy Statement: https://www.ibm.com/privacy/