CVE-2024-50275

CVE-2024-50275

High · published November 19, 2024

CVSS v3.1
7.3
EPSS
0%
Percentile
14.5
In the wild
Unconfirmed
What it is

In the Linux kernel, the following vulnerability has been resolved:

arm64/sve: Discard stale CPU state when handling SVE traps

The logic for handling SVE traps manipulates saved FPSIMD/SVE state

incorrectly, and a race with preemption can result in a task having

TIF_SVE set and TIF_FOREIGN_FPSTATE clear even though the live CPU state

is stale (e.g. with SVE traps enabled). This has been observed to result

in warnings from do_sve_acc() where SVE traps are not expected while

TIF_SVE is set:

| if (test_and_set_thread_flag(TIF_SVE))

| WARN_ON(1); /* SVE access shouldn't have trapped */

Warnings of this form have been reported intermittently, e.g.

https://lore.kernel.org/linux-arm-kernel/CA+G9fYtEGe_DhY2Ms7+L7NKsLYUomGsgqpdBj+QwDLeSg=JhGg@mail.gmail.com/

https://lore.kernel.org/linux-arm-kernel/[email protected]/

The race can occur when the SVE trap handler is preempted before and

after manipulating the saved FPSIMD/SVE state, starting and ending on

the same CPU, e.g.

| void do_sve_acc(unsigned long esr, struct pt_regs *regs)

| {

| // Trap on CPU 0 with TIF_SVE clear, SVE traps enabled

| // task->fpsimd_cpu is 0.

| // per_cpu_ptr(&fpsimd_last_state, 0) is task.

|

| ...

|

| // Preempted; migrated from CPU 0 to CPU 1.

| // TIF_FOREIGN_FPSTATE is set.

|

| get_cpu_fpsimd_context();

|

| if (test_and_set_thread_flag(TIF_SVE))

| WARN_ON(1); /* SVE access shouldn't have trapped */

|

| sve_init_regs() {

| if (!test_thread_flag(TIF_FOREIGN_FPSTATE)) {

| ...

| } else {

| fpsimd_to_sve(current);

| current->thread.fp_type = FP_STATE_SVE;

| }

| }

|

| put_cpu_fpsimd_context();

|

| // Preempted; migrated from CPU 1 to CPU 0.

| // task->fpsimd_cpu is still 0

| // If per_cpu_ptr(&fpsimd_last_state, 0) is still task then:

| // - Stale HW state is reused (with SVE traps enabled)

| // - TIF_FOREIGN_FPSTATE is cleared

| // - A return to userspace skips HW state restore

| }

Fix the case where the state is not live and TIF_FOREIGN_FPSTATE is set

by calling fpsimd_flush_task_state() to detach from the saved CPU

state. This ensures that a subsequent context switch will not reuse the

stale CPU state, and will instead set TIF_FOREIGN_FPSTATE, forcing the

new state to be reloaded from memory prior to a return to userspace.

The record
Technical detail
CVSS v3.1
7.3 · HIGH
Vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:L/A:H
CVSS v4.0
Not supplied
EPSS
0.00242 · 14.5th percentile
Published
2024-11-19T07:16Z
Affected products (8)
ProductVersionsFixed in
linux/linux_kernel≥ 5.13, < 6.6.616.6.61
linux/linux_kernel≥ 6.7, < 6.11.86.11.8
linux/linux_kernelall versions—
linux/linux_kernelall versions—
linux/linux_kernelall versions—
linux/linux_kernelall versions—
linux/linux_kernelall versions—
linux/linux_kernelall versions—
References (6)
EPSS history
Timeline
  • 19 NOV 01:30Z
    arm64/sve: Discard stale CPU state when handling SVE traps
    cvelistv5