Re: [PATCH v14 14/19] unwind_user: Flexible FP/RA recovery rules
Jens Remus <[email protected]> Mon, 18 May 2026 17:08:12 +0200
| Newsgroups | dev.linux.lists.sashiko,org.kernel.vger.bpf |
|---|---|
| Organization | IBM Deutschland Research & Development GmbH |
| Message-ID | <[email protected]> |
On 5/5/2026 8:34 PM, [email protected] wrote: > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: > - [High] Unprivileged users can trigger a kernel warning (and panic if panic_on_warn is set) by providing crafted SFrame data that forces the use of unimplemented register recovery rules. > -- > > commit 32f67c3538981cd61e598218f28891cb4051e567 > Author: Jens Remus <[email protected]> > > unwind_user: Flexible FP/RA recovery rules > > This commit adds support for flexible frame pointer and return address > recovery rules to the user unwinder. It introduces rules to retain values > or read them from registers. > >> diff --git a/include/linux/unwind_user.h b/include/linux/unwind_user.h >> index bc2edae399556..92cdf38c8aded 100644 >> --- a/include/linux/unwind_user.h >> +++ b/include/linux/unwind_user.h >> @@ -32,6 +32,15 @@ static inline int unwind_user_get_ra_reg(unsigned long *val) >> #define unwind_user_get_ra_reg unwind_user_get_ra_reg >> #endif >> >> +#ifndef unwind_user_get_reg >> +static inline int unwind_user_get_reg(unsigned long *val, unsigned int regnum) >> +{ >> + WARN_ON_ONCE(1); >> + return -EINVAL; Replace with the following to resolve below issue: dbg_once("unwind_user_get_reg(%u) not implemented\n", regnum); >> +} >> +#define unwind_user_get_reg unwind_user_get_reg >> +#endif > > Could an unprivileged user trigger these WARN_ON_ONCE macros by providing > crafted SFrame data during profiling? Valid. On architectures that do not support SFrame V3 flexible FDEs and therefore do not implement unwind_user_get_ra_reg(), such as arm64, above WARN_ON_ONCE(1) can be triggered using forged .sframe that maliciously has SFrame flexible FDE/FRE that encode the FP/RA recovery rule as register + offset or *(register + offset), with register != SP/FP. > > If an architecture does not implement unwind_user_get_reg or > unwind_user_get_ra_reg, falling back to these stubs will execute a kernel > warning. On systems with panic_on_warn enabled, this could lead to a > kernel panic. > > [ ... ] > >> diff --git a/kernel/unwind/user.c b/kernel/unwind/user.c >> index 9ceef9b2b8db0..89aecfbe3e849 100644 >> --- a/kernel/unwind/user.c >> +++ b/kernel/unwind/user.c >> @@ -61,22 +61,61 @@ static int unwind_user_next_common(struct unwind_user_state *state, > [ ... ] >> + switch (frame->ra.rule) { >> + case UNWIND_USER_RULE_RETAIN: >> if (!state->topmost || unwind_user_get_ra_reg(&ra)) >> return -EINVAL; >> + break; > [ ... ] >> + default: >> + WARN_ON_ONCE(1); >> + return -EINVAL; >> } > > A similar issue seems to exist in the default case here, as well as the > default case for frame->fp.rule below it. Resolve by explicitly handling all defined enum values. Keep the WARN_ON_ONCE(1) to detect errors if extending the related enums. > > Since sframe_init_rule_data() sets the rule based on untrusted user memory > (for example, setting UNWIND_USER_RULE_RETAIN when ra_off is 0), can a > crafted binary intentionally hit these paths? > > Would it be safer to silently fail and return -EINVAL when an unsupported > or unimplemented rule is encountered, rather than warning? > 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/