CVE-2022-49888
Publication date:
01/05/2025
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
arm64: entry: avoid kprobe recursion<br />
<br />
The cortex_a76_erratum_1463225_debug_handler() function is called when<br />
handling debug exceptions (and synchronous exceptions from BRK<br />
instructions), and so is called when a probed function executes. If the<br />
compiler does not inline cortex_a76_erratum_1463225_debug_handler(), it<br />
can be probed.<br />
<br />
If cortex_a76_erratum_1463225_debug_handler() is probed, any debug<br />
exception or software breakpoint exception will result in recursive<br />
exceptions leading to a stack overflow. This can be triggered with the<br />
ftrace multiple_probes selftest, and as per the example splat below.<br />
<br />
This is a regression caused by commit:<br />
<br />
6459b8469753e9fe ("arm64: entry: consolidate Cortex-A76 erratum 1463225 workaround")<br />
<br />
... which removed the NOKPROBE_SYMBOL() annotation associated with the<br />
function.<br />
<br />
My intent was that cortex_a76_erratum_1463225_debug_handler() would be<br />
inlined into its caller, el1_dbg(), which is marked noinstr and cannot<br />
be probed. Mark cortex_a76_erratum_1463225_debug_handler() as<br />
__always_inline to ensure this.<br />
<br />
Example splat prior to this patch (with recursive entries elided):<br />
<br />
| # echo p cortex_a76_erratum_1463225_debug_handler > /sys/kernel/debug/tracing/kprobe_events<br />
| # echo p do_el0_svc >> /sys/kernel/debug/tracing/kprobe_events<br />
| # echo 1 > /sys/kernel/debug/tracing/events/kprobes/enable<br />
| Insufficient stack space to handle exception!<br />
| ESR: 0x0000000096000047 -- DABT (current EL)<br />
| FAR: 0xffff800009cefff0<br />
| Task stack: [0xffff800009cf0000..0xffff800009cf4000]<br />
| IRQ stack: [0xffff800008000000..0xffff800008004000]<br />
| Overflow stack: [0xffff00007fbc00f0..0xffff00007fbc10f0]<br />
| CPU: 0 PID: 145 Comm: sh Not tainted 6.0.0 #2<br />
| Hardware name: linux,dummy-virt (DT)<br />
| pstate: 604003c5 (nZCv DAIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)<br />
| pc : arm64_enter_el1_dbg+0x4/0x20<br />
| lr : el1_dbg+0x24/0x5c<br />
| sp : ffff800009cf0000<br />
| x29: ffff800009cf0000 x28: ffff000002c74740 x27: 0000000000000000<br />
| x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000000<br />
| x23: 00000000604003c5 x22: ffff80000801745c x21: 0000aaaac95ac068<br />
| x20: 00000000f2000004 x19: ffff800009cf0040 x18: 0000000000000000<br />
| x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000<br />
| x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000<br />
| x11: 0000000000000010 x10: ffff800008c87190 x9 : ffff800008ca00d0<br />
| x8 : 000000000000003c x7 : 0000000000000000 x6 : 0000000000000000<br />
| x5 : 0000000000000000 x4 : 0000000000000000 x3 : 00000000000043a4<br />
| x2 : 00000000f2000004 x1 : 00000000f2000004 x0 : ffff800009cf0040<br />
| Kernel panic - not syncing: kernel stack overflow<br />
| CPU: 0 PID: 145 Comm: sh Not tainted 6.0.0 #2<br />
| Hardware name: linux,dummy-virt (DT)<br />
| Call trace:<br />
| dump_backtrace+0xe4/0x104<br />
| show_stack+0x18/0x4c<br />
| dump_stack_lvl+0x64/0x7c<br />
| dump_stack+0x18/0x38<br />
| panic+0x14c/0x338<br />
| test_taint+0x0/0x2c<br />
| panic_bad_stack+0x104/0x118<br />
| handle_bad_stack+0x34/0x48<br />
| __bad_stack+0x78/0x7c<br />
| arm64_enter_el1_dbg+0x4/0x20<br />
| el1h_64_sync_handler+0x40/0x98<br />
| el1h_64_sync+0x64/0x68<br />
| cortex_a76_erratum_1463225_debug_handler+0x0/0x34<br />
...<br />
| el1h_64_sync_handler+0x40/0x98<br />
| el1h_64_sync+0x64/0x68<br />
| cortex_a76_erratum_1463225_debug_handler+0x0/0x34<br />
...<br />
| el1h_64_sync_handler+0x40/0x98<br />
| el1h_64_sync+0x64/0x68<br />
| cortex_a76_erratum_1463225_debug_handler+0x0/0x34<br />
| el1h_64_sync_handler+0x40/0x98<br />
| el1h_64_sync+0x64/0x68<br />
| do_el0_svc+0x0/0x28<br />
| el0t_64_sync_handler+0x84/0xf0<br />
| el0t_64_sync+0x18c/0x190<br />
| Kernel Offset: disabled<br />
| CPU features: 0x0080,00005021,19001080<br />
| Memory Limit: none<br />
| ---[ end Kernel panic - not syncing: kernel stack overflow ]---<br />
<br />
With this patch, cortex_a76_erratum_1463225_debug_handler() is inlined<br />
into el1_dbg(), and el1_dbg() cannot be probed:<br />
<br />
| # echo p cortex_a76_erratum_1463225_debug_handler > /sys/kernel/debug/tracing/kprobe_events<br />
| sh: write error: No such file or directory<br />
| # grep -w cortex_a76_errat<br />
---truncated---
Severity CVSS v4.0: Pending analysis
Last modification:
07/05/2025