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/