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