CVE-2025-39863
Gravedad:
Pendiente de análisis
Tipo:
No Disponible / Otro tipo
Fecha de publicación:
19/09/2025
Última modificación:
19/09/2025
Descripción
*** Pendiente de traducción *** In the Linux kernel, the following vulnerability has been resolved:<br />
<br />
wifi: brcmfmac: fix use-after-free when rescheduling brcmf_btcoex_info work<br />
<br />
The brcmf_btcoex_detach() only shuts down the btcoex timer, if the<br />
flag timer_on is false. However, the brcmf_btcoex_timerfunc(), which<br />
runs as timer handler, sets timer_on to false. This creates critical<br />
race conditions:<br />
<br />
1.If brcmf_btcoex_detach() is called while brcmf_btcoex_timerfunc()<br />
is executing, it may observe timer_on as false and skip the call to<br />
timer_shutdown_sync().<br />
<br />
2.The brcmf_btcoex_timerfunc() may then reschedule the brcmf_btcoex_info<br />
worker after the cancel_work_sync() has been executed, resulting in<br />
use-after-free bugs.<br />
<br />
The use-after-free bugs occur in two distinct scenarios, depending on<br />
the timing of when the brcmf_btcoex_info struct is freed relative to<br />
the execution of its worker thread.<br />
<br />
Scenario 1: Freed before the worker is scheduled<br />
<br />
The brcmf_btcoex_info is deallocated before the worker is scheduled.<br />
A race condition can occur when schedule_work(&bt_local->work) is<br />
called after the target memory has been freed. The sequence of events<br />
is detailed below:<br />
<br />
CPU0 | CPU1<br />
brcmf_btcoex_detach | brcmf_btcoex_timerfunc<br />
| bt_local->timer_on = false;<br />
if (cfg->btcoex->timer_on) |<br />
... |<br />
cancel_work_sync(); |<br />
... |<br />
kfree(cfg->btcoex); // FREE |<br />
| schedule_work(&bt_local->work); // USE<br />
<br />
Scenario 2: Freed after the worker is scheduled<br />
<br />
The brcmf_btcoex_info is freed after the worker has been scheduled<br />
but before or during its execution. In this case, statements within<br />
the brcmf_btcoex_handler() — such as the container_of macro and<br />
subsequent dereferences of the brcmf_btcoex_info object will cause<br />
a use-after-free access. The following timeline illustrates this<br />
scenario:<br />
<br />
CPU0 | CPU1<br />
brcmf_btcoex_detach | brcmf_btcoex_timerfunc<br />
| bt_local->timer_on = false;<br />
if (cfg->btcoex->timer_on) |<br />
... |<br />
cancel_work_sync(); |<br />
... | schedule_work(); // Reschedule<br />
|<br />
kfree(cfg->btcoex); // FREE | brcmf_btcoex_handler() // Worker<br />
/* | btci = container_of(....); // USE<br />
The kfree() above could | ...<br />
also occur at any point | btci-> // USE<br />
during the worker&#39;s execution|<br />
*/ |<br />
<br />
To resolve the race conditions, drop the conditional check and call<br />
timer_shutdown_sync() directly. It can deactivate the timer reliably,<br />
regardless of its current state. Once stopped, the timer_on state is<br />
then set to false.