blob: c89287654872e24980c2964c8652a43ea5738b8a [file]
The CVE, designated as CVE-2021-46957, affects the Linux kernel's kprobes feature on RISC-V architectures. Specifically, it occurs when a kprobe is installed at the entry point of the `sys_read` system call.
When the kernel reaches the `ebreak` instruction inserted by the kprobe, it traps into the breakpoint handler, which sets up for single-stepping the original instruction and disables interrupts by clearing the `SIE` bit in the `sstatus` register. However, when the kernel restores to the original instruction slot, an "Instruction page fault" exception is triggered if the Page Table Entry (PTE) for that slot is not filled.
The kernel then traps into the page fault handler, which resets the kprobe and returns the program counter (`pc`) to the probe address. This causes the kernel to trap into the breakpoint handler again, but this time with an `sstatus` register value without the `SIE` bit set.
When the kernel crosses the probe, it restores the `sstatus` CSR with a value that does not have the `SIE` bit set, which is incorrect. This leads to a BUG_ON() in the `__find_get_block` function, which requires interrupts to be enabled.
The fix for this issue involves restoring the backed-up `sstatus` register value when single-stepping an instruction causes a page fault.
The affected kernel versions are 5.12 and 5.13, with the issue introduced by commit c22b0bcb1dd0 and fixed in commits fd0f06590d35 (for 5.12.3) and b1ebaa0e1318 (for 5.13). The affected file is `arch/riscv/kernel/probes/kprobes.c`.