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
Related
Published
2025-05-01T15:16:01Z
Modified
2025-05-02T13:53:20Z
Summary
[none]
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

Debian:12 / linux

Package

Name
linux
Purl
pkg:deb/debian/linux?arch=source

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0Unknown introduced version / All previous versions are affected
Fixed
6.0.10-1

Ecosystem specific

{
    "urgency": "not yet assigned"
}

Debian:13 / linux

Package

Name
linux
Purl
pkg:deb/debian/linux?arch=source

Affected ranges

Type
ECOSYSTEM
Events
Introduced
0Unknown introduced version / All previous versions are affected
Fixed
6.0.10-1

Ecosystem specific

{
    "urgency": "not yet assigned"
}