CVE-2021-46939

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
27/02/2024
Last modified:
22/04/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> tracing: Restructure trace_clock_global() to never block<br /> <br /> It was reported that a fix to the ring buffer recursion detection would<br /> cause a hung machine when performing suspend / resume testing. The<br /> following backtrace was extracted from debugging that case:<br /> <br /> Call Trace:<br /> trace_clock_global+0x91/0xa0<br /> __rb_reserve_next+0x237/0x460<br /> ring_buffer_lock_reserve+0x12a/0x3f0<br /> trace_buffer_lock_reserve+0x10/0x50<br /> __trace_graph_return+0x1f/0x80<br /> trace_graph_return+0xb7/0xf0<br /> ? trace_clock_global+0x91/0xa0<br /> ftrace_return_to_handler+0x8b/0xf0<br /> ? pv_hash+0xa0/0xa0<br /> return_to_handler+0x15/0x30<br /> ? ftrace_graph_caller+0xa0/0xa0<br /> ? trace_clock_global+0x91/0xa0<br /> ? __rb_reserve_next+0x237/0x460<br /> ? ring_buffer_lock_reserve+0x12a/0x3f0<br /> ? trace_event_buffer_lock_reserve+0x3c/0x120<br /> ? trace_event_buffer_reserve+0x6b/0xc0<br /> ? trace_event_raw_event_device_pm_callback_start+0x125/0x2d0<br /> ? dpm_run_callback+0x3b/0xc0<br /> ? pm_ops_is_empty+0x50/0x50<br /> ? platform_get_irq_byname_optional+0x90/0x90<br /> ? trace_device_pm_callback_start+0x82/0xd0<br /> ? dpm_run_callback+0x49/0xc0<br /> <br /> With the following RIP:<br /> <br /> RIP: 0010:native_queued_spin_lock_slowpath+0x69/0x200<br /> <br /> Since the fix to the recursion detection would allow a single recursion to<br /> happen while tracing, this lead to the trace_clock_global() taking a spin<br /> lock and then trying to take it again:<br /> <br /> ring_buffer_lock_reserve() {<br /> trace_clock_global() {<br /> arch_spin_lock() {<br /> queued_spin_lock_slowpath() {<br /> /* lock taken */<br /> (something else gets traced by function graph tracer)<br /> ring_buffer_lock_reserve() {<br /> trace_clock_global() {<br /> arch_spin_lock() {<br /> queued_spin_lock_slowpath() {<br /> /* DEAD LOCK! */<br /> <br /> Tracing should *never* block, as it can lead to strange lockups like the<br /> above.<br /> <br /> Restructure the trace_clock_global() code to instead of simply taking a<br /> lock to update the recorded "prev_time" simply use it, as two events<br /> happening on two different CPUs that calls this at the same time, really<br /> doesn&amp;#39;t matter which one goes first. Use a trylock to grab the lock for<br /> updating the prev_time, and if it fails, simply try again the next time.<br /> If it failed to be taken, that means something else is already updating<br /> it.<br /> <br /> <br /> Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=212761

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 2.6.30 (including) 4.4.269 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 4.5.0 (including) 4.9.269 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 4.10.0 (including) 4.14.233 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 4.15.0 (including) 4.19.191 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 4.20.0 (including) 5.4.118 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.5.0 (including) 5.10.36 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.11.0 (including) 5.11.20 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.12.0 (including) 5.12.3 (excluding)