CVE-2024-42239

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

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> bpf: Fail bpf_timer_cancel when callback is being cancelled<br /> <br /> Given a schedule:<br /> <br /> timer1 cb timer2 cb<br /> <br /> bpf_timer_cancel(timer2); bpf_timer_cancel(timer1);<br /> <br /> Both bpf_timer_cancel calls would wait for the other callback to finish<br /> executing, introducing a lockup.<br /> <br /> Add an atomic_t count named &amp;#39;cancelling&amp;#39; in bpf_hrtimer. This keeps<br /> track of all in-flight cancellation requests for a given BPF timer.<br /> Whenever cancelling a BPF timer, we must check if we have outstanding<br /> cancellation requests, and if so, we must fail the operation with an<br /> error (-EDEADLK) since cancellation is synchronous and waits for the<br /> callback to finish executing. This implies that we can enter a deadlock<br /> situation involving two or more timer callbacks executing in parallel<br /> and attempting to cancel one another.<br /> <br /> Note that we avoid incrementing the cancelling counter for the target<br /> timer (the one being cancelled) if bpf_timer_cancel is not invoked from<br /> a callback, to avoid spurious errors. The whole point of detecting<br /> cur-&gt;cancelling and returning -EDEADLK is to not enter a busy wait loop<br /> (which may or may not lead to a lockup). This does not apply in case the<br /> caller is in a non-callback context, the other side can continue to<br /> cancel as it sees fit without running into errors.<br /> <br /> Background on prior attempts:<br /> <br /> Earlier versions of this patch used a bool &amp;#39;cancelling&amp;#39; bit and used the<br /> following pattern under timer-&gt;lock to publish cancellation status.<br /> <br /> lock(t-&gt;lock);<br /> t-&gt;cancelling = true;<br /> mb();<br /> if (cur-&gt;cancelling)<br /> return -EDEADLK;<br /> unlock(t-&gt;lock);<br /> hrtimer_cancel(t-&gt;timer);<br /> t-&gt;cancelling = false;<br /> <br /> The store outside the critical section could overwrite a parallel<br /> requests t-&gt;cancelling assignment to true, to ensure the parallely<br /> executing callback observes its cancellation status.<br /> <br /> It would be necessary to clear this cancelling bit once hrtimer_cancel<br /> is done, but lack of serialization introduced races. Another option was<br /> explored where bpf_timer_start would clear the bit when (re)starting the<br /> timer under timer-&gt;lock. This would ensure serialized access to the<br /> cancelling bit, but may allow it to be cleared before in-flight<br /> hrtimer_cancel has finished executing, such that lockups can occur<br /> again.<br /> <br /> Thus, we choose an atomic counter to keep track of all outstanding<br /> cancellation requests and use it to prevent lockups in case callbacks<br /> attempt to cancel each other while executing in parallel.

Vulnerable products and versions

CPE From Up to
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 5.15 (including) 6.6.41 (excluding)
cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* 6.7 (including) 6.9.10 (excluding)