CVE-2022-49783

Source
https://nvd.nist.gov/vuln/detail/CVE-2022-49783
Import Source
https://storage.googleapis.com/osv-test-cve-osv-conversion/osv-output/CVE-2022-49783.json
JSON Data
https://api.test.osv.dev/v1/vulns/CVE-2022-49783
Downstream
Related
Published
2025-05-01T14:09:17Z
Modified
2025-10-16T00:32:25.861637Z
Summary
x86/fpu: Drop fpregs lock before inheriting FPU permissions
Details

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

x86/fpu: Drop fpregs lock before inheriting FPU permissions

Mike Galbraith reported the following against an old fork of preempt-rt but the same issue also applies to the current preempt-rt tree.

BUG: sleeping function called from invalid context at kernel/locking/spinlockrt.c:46 inatomic(): 1, irqsdisabled(): 0, nonblock: 0, pid: 1, name: systemd preemptcount: 1, expected: 0 RCU nest depth: 0, expected: 0 Preemption disabled at: fpuclone CPU: 6 PID: 1 Comm: systemd Tainted: G E (unreleased) Call Trace: <TASK> dumpstacklvl ? fpuclone _mightresched rtspinlock fpuclone ? copythread ? copyprocess ? shmemallocinode ? kmemcachealloc ? kernelclone ? _dosysclone ? dosyscall64 ? _x64sysrtsigprocmask ? syscallexittousermode ? dosyscall64 ? syscallexittousermode ? dosyscall64 ? syscallexittousermode ? dosyscall64 ? excpagefault ? entrySYSCALL64afterhwframe </TASK>

Mike says:

The splat comes from fpuinheritperms() being called under fpregslock(), and us reaching the spinlockirq() therein due to fpustatesizedynamic() returning true despite static key _fpustatesizedynamic having never been enabled.

Mike's assessment looks correct. fpregslock on a PREEMPTRT kernel disables preemption so calling spinlockirq() in fpuinheritperms() is unsafe. This problem exists since commit

9e798e9aa14c ("x86/fpu: Prepare fpu_clone() for dynamically enabled features").

Even though the original bug report should not have enabled the paths at all, the bug still exists.

fpregslock is necessary when editing the FPU registers or a task's FP state but it is not necessary for fpuinheritperms(). The only write of any FP state in fpuinheritperms() is for the new child which is not running yet and cannot context switch or be borrowed by a kernel thread yet. Hence, fpregslock is not protecting anything in the new child until clone() completes and can be dropped earlier. The siglock still needs to be acquired by fpuinheritperms() as the read of the parent's permissions has to be serialised.

[ bp: Cleanup splat. ]

References

Affected packages

Git / git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git

Affected ranges

Type
GIT
Repo
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
Events
Introduced
9e798e9aa14c45fb94e47b30bf6347b369ce9df7
Fixed
c6e8a7a1780af3da65e78a615f7d0874da6aabb0
Type
GIT
Repo
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
Events
Introduced
9e798e9aa14c45fb94e47b30bf6347b369ce9df7
Fixed
36b038791e1e2baea892e9276588815fd14894b4

Affected versions

v5.*

v5.15
v5.15-rc6
v5.15-rc7
v5.16
v5.16-rc1
v5.16-rc2
v5.16-rc3
v5.16-rc4
v5.16-rc5
v5.16-rc6
v5.16-rc7
v5.16-rc8
v5.17
v5.17-rc1
v5.17-rc2
v5.17-rc3
v5.17-rc4
v5.17-rc5
v5.17-rc6
v5.17-rc7
v5.17-rc8
v5.18
v5.18-rc1
v5.18-rc2
v5.18-rc3
v5.18-rc4
v5.18-rc5
v5.18-rc6
v5.18-rc7
v5.19
v5.19-rc1
v5.19-rc2
v5.19-rc3
v5.19-rc4
v5.19-rc5
v5.19-rc6
v5.19-rc7
v5.19-rc8

v6.*

v6.0
v6.0-rc1
v6.0-rc2
v6.0-rc3
v6.0-rc4
v6.0-rc5
v6.0-rc6
v6.0-rc7
v6.0.1
v6.0.2
v6.0.3
v6.0.4
v6.0.5
v6.0.6
v6.0.7
v6.0.8
v6.0.9
v6.1-rc1
v6.1-rc2
v6.1-rc3
v6.1-rc4

Linux / Kernel

Package

Name
Kernel

Affected ranges

Type
ECOSYSTEM
Events
Introduced
5.16.0
Fixed
6.0.10