// For flags

CVE-2024-26698

hv_netvsc: Fix race condition between netvsc_probe and netvsc_remove

Severity Score

4.1
*CVSS v3.1

Exploit Likelihood

*EPSS

Affected Versions

*CPE

Public Exploits

0
*Multiple Sources

Exploited in Wild

-
*KEV

Decision

Track
*SSVC
Descriptions

In the Linux kernel, the following vulnerability has been resolved: hv_netvsc: Fix race condition between netvsc_probe and netvsc_remove In commit ac5047671758 ("hv_netvsc: Disable NAPI before closing the
VMBus channel"), napi_disable was getting called for all channels,
including all subchannels without confirming if they are enabled or not. This caused hv_netvsc getting hung at napi_disable, when netvsc_probe()
has finished running but nvdev->subchan_work has not started yet.
netvsc_subchan_work() -> rndis_set_subchannel() has not created the
sub-channels and because of that netvsc_sc_open() is not running.
netvsc_remove() calls cancel_work_sync(&nvdev->subchan_work), for which
netvsc_subchan_work did not run. netif_napi_add() sets the bit NAPI_STATE_SCHED because it ensures NAPI
cannot be scheduled. Then netvsc_sc_open() -> napi_enable will clear the
NAPIF_STATE_SCHED bit, so it can be scheduled. napi_disable() does the
opposite. Now during netvsc_device_remove(), when napi_disable is called for those
subchannels, napi_disable gets stuck on infinite msleep. This fix addresses this problem by ensuring that napi_disable() is not
getting called for non-enabled NAPI struct.
But netif_napi_del() is still necessary for these non-enabled NAPI struct
for cleanup purpose. Call trace:
[ 654.559417] task:modprobe state:D stack: 0 pid: 2321 ppid: 1091 flags:0x00004002
[ 654.568030] Call Trace:
[ 654.571221] <TASK>
[ 654.573790] __schedule+0x2d6/0x960
[ 654.577733] schedule+0x69/0xf0
[ 654.581214] schedule_timeout+0x87/0x140
[ 654.585463] ? __bpf_trace_tick_stop+0x20/0x20
[ 654.590291] msleep+0x2d/0x40
[ 654.593625] napi_disable+0x2b/0x80
[ 654.597437] netvsc_device_remove+0x8a/0x1f0 [hv_netvsc]
[ 654.603935] rndis_filter_device_remove+0x194/0x1c0 [hv_netvsc]
[ 654.611101] ? do_wait_intr+0xb0/0xb0
[ 654.615753] netvsc_remove+0x7c/0x120 [hv_netvsc]
[ 654.621675] vmbus_remove+0x27/0x40 [hv_vmbus]

En el kernel de Linux, se resolvió la siguiente vulnerabilidad: hv_netvsc: corrige la condición de ejecución entre netvsc_probe y netvsc_remove En el commit ac5047671758 ("hv_netvsc: deshabilite NAPI antes de cerrar el canal VMBus"), se llamaba a napi_disable para todos los canales, incluidos todos los subcanales sin confirmando si están habilitados o no. Esto provocó que hv_netvsc se colgara en napi_disable, cuando netvsc_probe() terminó de ejecutarse pero nvdev-&gt;subchan_work aún no se inició. netvsc_subchan_work() -&gt; rndis_set_subchannel() no ha creado los subcanales y por eso netvsc_sc_open() no se está ejecutando. netvsc_remove() llama a cancel_work_sync(&amp;nvdev-&gt;subchan_work), para lo cual netvsc_subchan_work no se ejecutó. netif_napi_add() establece el bit NAPI_STATE_SCHED porque garantiza que NAPI no se pueda programar. Luego netvsc_sc_open() -&gt; napi_enable borrará el bit NAPIF_STATE_SCHED, para que pueda programarse. napi_disable() hace lo contrario. Ahora, durante netvsc_device_remove(), cuando se llama a napi_disable para esos subcanales, napi_disable se atasca en msleep infinito. Esta solución soluciona este problema garantizando que no se llame a napi_disable() para una estructura NAPI no habilitada. Pero netif_napi_del() sigue siendo necesario para estas estructuras NAPI no habilitadas con fines de limpieza. Rastreo de llamadas: [654.559417] tarea:modprobe estado:D pila: 0 pid: 2321 ppid: 1091 banderas:0x00004002 [654.568030] Rastreo de llamadas: [654.571221] [654.573790] __schedule+0x2d6/0x960 [ 65 4.577733] horario+0x69 /0xf0 [654.581214] Schedule_timeout+0x87/0x140 [654.585463]? __bpf_trace_tick_stop+0x20/0x20 [ 654.590291] msleep+0x2d/0x40 [ 654.593625] napi_disable+0x2b/0x80 [ 654.597437] netvsc_device_remove+0x8a/0x1f0 [hv_netvsc] [ 6 54.603935] rndis_filter_device_remove+0x194/0x1c0 [hv_netvsc] [654.611101]? do_wait_intr+0xb0/0xb0 [ 654.615753] netvsc_remove+0x7c/0x120 [hv_netvsc] [ 654.621675] vmbus_remove+0x27/0x40 [hv_vmbus]

A vulnerability was found in the hv_netvsc driver in the Linux kernel, where a race condition is present between the netvsc_probe() and netvsc_remove() functions. This race condition could lead to system hangs during network device removal.

In the Linux kernel, the following vulnerability has been resolved: hv_netvsc: Fix race condition between netvsc_probe and netvsc_remove In commit ac5047671758 ("hv_netvsc: Disable NAPI before closing the VMBus channel"), napi_disable was getting called for all channels, including all subchannels without confirming if they are enabled or not. This caused hv_netvsc getting hung at napi_disable, when netvsc_probe() has finished running but nvdev->subchan_work has not started yet. netvsc_subchan_work() -> rndis_set_subchannel() has not created the sub-channels and because of that netvsc_sc_open() is not running. netvsc_remove() calls cancel_work_sync(&nvdev->subchan_work), for which netvsc_subchan_work did not run. netif_napi_add() sets the bit NAPI_STATE_SCHED because it ensures NAPI cannot be scheduled. Then netvsc_sc_open() -> napi_enable will clear the NAPIF_STATE_SCHED bit, so it can be scheduled. napi_disable() does the opposite. Now during netvsc_device_remove(), when napi_disable is called for those subchannels, napi_disable gets stuck on infinite msleep. This fix addresses this problem by ensuring that napi_disable() is not getting called for non-enabled NAPI struct. But netif_napi_del() is still necessary for these non-enabled NAPI struct for cleanup purpose. Call trace: [ 654.559417] task:modprobe state:D stack: 0 pid: 2321 ppid: 1091 flags:0x00004002 [ 654.568030] Call Trace: [ 654.571221] <TASK> [ 654.573790] __schedule+0x2d6/0x960 [ 654.577733] schedule+0x69/0xf0 [ 654.581214] schedule_timeout+0x87/0x140 [ 654.585463] ? __bpf_trace_tick_stop+0x20/0x20 [ 654.590291] msleep+0x2d/0x40 [ 654.593625] napi_disable+0x2b/0x80 [ 654.597437] netvsc_device_remove+0x8a/0x1f0 [hv_netvsc] [ 654.603935] rndis_filter_device_remove+0x194/0x1c0 [hv_netvsc] [ 654.611101] ? do_wait_intr+0xb0/0xb0 [ 654.615753] netvsc_remove+0x7c/0x120 [hv_netvsc] [ 654.621675] vmbus_remove+0x27/0x40 [hv_vmbus]

*Credits: N/A
CVSS Scores
Attack Vector
Local
Attack Complexity
High
Privileges Required
High
User Interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High
Attack Vector
Local
Attack Complexity
Low
Authentication
Single
Confidentiality
None
Integrity
None
Availability
Complete
* Common Vulnerability Scoring System
SSVC
  • Decision:Track
Exploitation
None
Automatable
No
Tech. Impact
Partial
* Organization's Worst-case Scenario
Timeline
  • 2024-02-19 CVE Reserved
  • 2024-04-03 CVE Published
  • 2024-04-04 EPSS Updated
  • 2024-12-19 CVE Updated
  • ---------- Exploited in Wild
  • ---------- KEV Due Date
  • ---------- First Exploit
CWE
  • CWE-362: Concurrent Execution using Shared Resource with Improper Synchronization ('Race Condition')
CAPEC
Affected Vendors, Products, and Versions
Vendor Product Version Other Status
Vendor Product Version Other Status <-- --> Vendor Product Version Other Status
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 5.8 < 5.10.210
Search vendor "Linux" for product "Linux Kernel" and version " >= 5.8 < 5.10.210"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 5.8 < 5.15.149
Search vendor "Linux" for product "Linux Kernel" and version " >= 5.8 < 5.15.149"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 5.8 < 6.1.79
Search vendor "Linux" for product "Linux Kernel" and version " >= 5.8 < 6.1.79"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 5.8 < 6.6.18
Search vendor "Linux" for product "Linux Kernel" and version " >= 5.8 < 6.6.18"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 5.8 < 6.7.6
Search vendor "Linux" for product "Linux Kernel" and version " >= 5.8 < 6.7.6"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 5.8 < 6.8
Search vendor "Linux" for product "Linux Kernel" and version " >= 5.8 < 6.8"
en
Affected