| From bippy-5f407fcff5a0 Mon Sep 17 00:00:00 2001 |
| From: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| To: <linux-cve-announce@vger.kernel.org> |
| Reply-to: <cve@kernel.org>, <linux-kernel@vger.kernel.org> |
| Subject: CVE-2024-35873: riscv: Fix vector state restore in rt_sigreturn() |
| |
| Description |
| =========== |
| |
| In the Linux kernel, the following vulnerability has been resolved: |
| |
| riscv: Fix vector state restore in rt_sigreturn() |
| |
| The RISC-V Vector specification states in "Appendix D: Calling |
| Convention for Vector State" [1] that "Executing a system call causes |
| all caller-saved vector registers (v0-v31, vl, vtype) and vstart to |
| become unspecified.". In the RISC-V kernel this is called "discarding |
| the vstate". |
| |
| Returning from a signal handler via the rt_sigreturn() syscall, vector |
| discard is also performed. However, this is not an issue since the |
| vector state should be restored from the sigcontext, and therefore not |
| care about the vector discard. |
| |
| The "live state" is the actual vector register in the running context, |
| and the "vstate" is the vector state of the task. A dirty live state, |
| means that the vstate and live state are not in synch. |
| |
| When vectorized user_from_copy() was introduced, an bug sneaked in at |
| the restoration code, related to the discard of the live state. |
| |
| An example when this go wrong: |
| |
| 1. A userland application is executing vector code |
| 2. The application receives a signal, and the signal handler is |
| entered. |
| 3. The application returns from the signal handler, using the |
| rt_sigreturn() syscall. |
| 4. The live vector state is discarded upon entering the |
| rt_sigreturn(), and the live state is marked as "dirty", indicating |
| that the live state need to be synchronized with the current |
| vstate. |
| 5. rt_sigreturn() restores the vstate, except the Vector registers, |
| from the sigcontext |
| 6. rt_sigreturn() restores the Vector registers, from the sigcontext, |
| and now the vectorized user_from_copy() is used. The dirty live |
| state from the discard is saved to the vstate, making the vstate |
| corrupt. |
| 7. rt_sigreturn() returns to the application, which crashes due to |
| corrupted vstate. |
| |
| Note that the vectorized user_from_copy() is invoked depending on the |
| value of CONFIG_RISCV_ISA_V_UCOPY_THRESHOLD. Default is 768, which |
| means that vlen has to be larger than 128b for this bug to trigger. |
| |
| The fix is simply to mark the live state as non-dirty/clean prior |
| performing the vstate restore. |
| |
| The Linux kernel CVE team has assigned CVE-2024-35873 to this issue. |
| |
| |
| Affected and fixed versions |
| =========================== |
| |
| Issue introduced in 6.8 with commit c2a658d419246108c9bf065ec347355de5ba8a05 and fixed in 6.8.5 with commit 5b16d904e910183181b9d90efa957c787a8ac91b |
| Issue introduced in 6.8 with commit c2a658d419246108c9bf065ec347355de5ba8a05 and fixed in 6.9 with commit c27fa53b858b4ee6552a719aa599c250cf98a586 |
| |
| Please see https://www.kernel.org for a full list of currently supported |
| kernel versions by the kernel community. |
| |
| Unaffected versions might change over time as fixes are backported to |
| older supported kernel versions. The official CVE entry at |
| https://cve.org/CVERecord/?id=CVE-2024-35873 |
| will be updated if fixes are backported, please check that for the most |
| up to date information about this issue. |
| |
| |
| Affected files |
| ============== |
| |
| The file(s) affected by this issue are: |
| arch/riscv/kernel/signal.c |
| |
| |
| Mitigation |
| ========== |
| |
| The Linux kernel CVE team recommends that you update to the latest |
| stable kernel version for this, and many other bugfixes. Individual |
| changes are never tested alone, but rather are part of a larger kernel |
| release. Cherry-picking individual commits is not recommended or |
| supported by the Linux kernel community at all. If however, updating to |
| the latest release is impossible, the individual changes to resolve this |
| issue can be found at these commits: |
| https://git.kernel.org/stable/c/5b16d904e910183181b9d90efa957c787a8ac91b |
| https://git.kernel.org/stable/c/c27fa53b858b4ee6552a719aa599c250cf98a586 |