CVE-2022-49782
Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
01/05/2025
Last modified:
02/05/2025
Description
In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
perf: Improve missing SIGTRAP checking<br />
<br />
To catch missing SIGTRAP we employ a WARN in __perf_event_overflow(),<br />
which fires if pending_sigtrap was already set: returning to user space<br />
without consuming pending_sigtrap, and then having the event fire again<br />
would re-enter the kernel and trigger the WARN.<br />
<br />
This, however, seemed to miss the case where some events not associated<br />
with progress in the user space task can fire and the interrupt handler<br />
runs before the IRQ work meant to consume pending_sigtrap (and generate<br />
the SIGTRAP).<br />
<br />
syzbot gifted us this stack trace:<br />
<br />
| WARNING: CPU: 0 PID: 3607 at kernel/events/core.c:9313 __perf_event_overflow<br />
| Modules linked in:<br />
| CPU: 0 PID: 3607 Comm: syz-executor100 Not tainted 6.1.0-rc2-syzkaller-00073-g88619e77b33d #0<br />
| Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/11/2022<br />
| RIP: 0010:__perf_event_overflow+0x498/0x540 kernel/events/core.c:9313<br />
| <br />
| Call Trace:<br />
| <br />
| perf_swevent_hrtimer+0x34f/0x3c0 kernel/events/core.c:10729<br />
| __run_hrtimer kernel/time/hrtimer.c:1685 [inline]<br />
| __hrtimer_run_queues+0x1c6/0xfb0 kernel/time/hrtimer.c:1749<br />
| hrtimer_interrupt+0x31c/0x790 kernel/time/hrtimer.c:1811<br />
| local_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1096 [inline]<br />
| __sysvec_apic_timer_interrupt+0x17c/0x640 arch/x86/kernel/apic/apic.c:1113<br />
| sysvec_apic_timer_interrupt+0x40/0xc0 arch/x86/kernel/apic/apic.c:1107<br />
| asm_sysvec_apic_timer_interrupt+0x16/0x20 arch/x86/include/asm/idtentry.h:649<br />
| <br />
| <br />
<br />
In this case, syzbot produced a program with event type<br />
PERF_TYPE_SOFTWARE and config PERF_COUNT_SW_CPU_CLOCK. The hrtimer<br />
manages to fire again before the IRQ work got a chance to run, all while<br />
never having returned to user space.<br />
<br />
Improve the WARN to check for real progress in user space: approximate<br />
this by storing a 32-bit hash of the current IP into pending_sigtrap,<br />
and if an event fires while pending_sigtrap still matches the previous<br />
IP, we assume no progress (false negatives are possible given we could<br />
return to user space and trigger again on the same IP).