CVE-2025-38170

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
03/07/2025
Last modified:
03/07/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> arm64/fpsimd: Discard stale CPU state when handling SME traps<br /> <br /> The logic for handling SME traps manipulates saved FPSIMD/SVE/SME state<br /> incorrectly, and a race with preemption can result in a task having<br /> TIF_SME set and TIF_FOREIGN_FPSTATE clear even though the live CPU state<br /> is stale (e.g. with SME traps enabled). This can result in warnings from<br /> do_sme_acc() where SME traps are not expected while TIF_SME is set:<br /> <br /> | /* With TIF_SME userspace shouldn&amp;#39;t generate any traps */<br /> | if (test_and_set_thread_flag(TIF_SME))<br /> | WARN_ON(1);<br /> <br /> This is very similar to the SVE issue we fixed in commit:<br /> <br /> 751ecf6afd6568ad ("arm64/sve: Discard stale CPU state when handling SVE traps")<br /> <br /> The race can occur when the SME trap handler is preempted before and<br /> after manipulating the saved FPSIMD/SVE/SME state, starting and ending on<br /> the same CPU, e.g.<br /> <br /> | void do_sme_acc(unsigned long esr, struct pt_regs *regs)<br /> | {<br /> | // Trap on CPU 0 with TIF_SME clear, SME traps enabled<br /> | // task-&gt;fpsimd_cpu is 0.<br /> | // per_cpu_ptr(&amp;fpsimd_last_state, 0) is task.<br /> |<br /> | ...<br /> |<br /> | // Preempted; migrated from CPU 0 to CPU 1.<br /> | // TIF_FOREIGN_FPSTATE is set.<br /> |<br /> | get_cpu_fpsimd_context();<br /> |<br /> | /* With TIF_SME userspace shouldn&amp;#39;t generate any traps */<br /> | if (test_and_set_thread_flag(TIF_SME))<br /> | WARN_ON(1);<br /> |<br /> | if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {<br /> | unsigned long vq_minus_one =<br /> | sve_vq_from_vl(task_get_sme_vl(current)) - 1;<br /> | sme_set_vq(vq_minus_one);<br /> |<br /> | fpsimd_bind_task_to_cpu();<br /> | }<br /> |<br /> | put_cpu_fpsimd_context();<br /> |<br /> | // Preempted; migrated from CPU 1 to CPU 0.<br /> | // task-&gt;fpsimd_cpu is still 0<br /> | // If per_cpu_ptr(&amp;fpsimd_last_state, 0) is still task then:<br /> | // - Stale HW state is reused (with SME traps enabled)<br /> | // - TIF_FOREIGN_FPSTATE is cleared<br /> | // - A return to userspace skips HW state restore<br /> | }<br /> <br /> Fix the case where the state is not live and TIF_FOREIGN_FPSTATE is set<br /> by calling fpsimd_flush_task_state() to detach from the saved CPU<br /> state. This ensures that a subsequent context switch will not reuse the<br /> stale CPU state, and will instead set TIF_FOREIGN_FPSTATE, forcing the<br /> new state to be reloaded from memory prior to a return to userspace.<br /> <br /> Note: this was originallly posted as [1].<br /> <br /> [ Rutland: rewrite commit message ]

Impact