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 &#39;cancelling&#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->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 &#39;cancelling&#39; bit and used the<br />
following pattern under timer->lock to publish cancellation status.<br />
<br />
lock(t->lock);<br />
t->cancelling = true;<br />
mb();<br />
if (cur->cancelling)<br />
return -EDEADLK;<br />
unlock(t->lock);<br />
hrtimer_cancel(t->timer);<br />
t->cancelling = false;<br />
<br />
The store outside the critical section could overwrite a parallel<br />
requests t->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->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.
Impact
Base Score 3.x
5.50
Severity 3.x
MEDIUM
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) |
To consult the complete list of CPE names with products and versions, see this page



