| 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`. |
| |