// For flags

CVE-2024-26687

xen/events: close evtchn after mapping cleanup

Severity Score

"-"
*CVSS v-

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:

xen/events: close evtchn after mapping cleanup

shutdown_pirq and startup_pirq are not taking the
irq_mapping_update_lock because they can't due to lock inversion. Both
are called with the irq_desc->lock being taking. The lock order,
however, is first irq_mapping_update_lock and then irq_desc->lock.

This opens multiple races:
- shutdown_pirq can be interrupted by a function that allocates an event
channel:

CPU0 CPU1
shutdown_pirq {
xen_evtchn_close(e)
__startup_pirq {
EVTCHNOP_bind_pirq
-> returns just freed evtchn e
set_evtchn_to_irq(e, irq)
}
xen_irq_info_cleanup() {
set_evtchn_to_irq(e, -1)
}
}

Assume here event channel e refers here to the same event channel
number.
After this race the evtchn_to_irq mapping for e is invalid (-1).

- __startup_pirq races with __unbind_from_irq in a similar way. Because
__startup_pirq doesn't take irq_mapping_update_lock it can grab the
evtchn that __unbind_from_irq is currently freeing and cleaning up. In
this case even though the event channel is allocated, its mapping can
be unset in evtchn_to_irq.

The fix is to first cleanup the mappings and then close the event
channel. In this way, when an event channel gets allocated it's
potential previous evtchn_to_irq mappings are guaranteed to be unset already.
This is also the reverse order of the allocation where first the event
channel is allocated and then the mappings are setup.

On a 5.10 kernel prior to commit 3fcdaf3d7634 ("xen/events: modify internal
[un]bind interfaces"), we hit a BUG like the following during probing of NVMe
devices. The issue is that during nvme_setup_io_queues, pci_free_irq
is called for every device which results in a call to shutdown_pirq.
With many nvme devices it's therefore likely to hit this race during
boot because there will be multiple calls to shutdown_pirq and
startup_pirq are running potentially in parallel.

------------[ cut here ]------------
blkfront: xvda: barrier or flush: disabled; persistent grants: enabled; indirect descriptors: enabled; bounce buffer: enabled
kernel BUG at drivers/xen/events/events_base.c:499!
invalid opcode: 0000 [#1] SMP PTI
CPU: 44 PID: 375 Comm: kworker/u257:23 Not tainted 5.10.201-191.748.amzn2.x86_64 #1
Hardware name: Xen HVM domU, BIOS 4.11.amazon 08/24/2006
Workqueue: nvme-reset-wq nvme_reset_work
RIP: 0010:bind_evtchn_to_cpu+0xdf/0xf0
Code: 5d 41 5e c3 cc cc cc cc 44 89 f7 e8 2b 55 ad ff 49 89 c5 48 85 c0 0f 84 64 ff ff ff 4c 8b 68 30 41 83 fe ff 0f 85 60 ff ff ff <0f> 0b 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 0f 1f 44 00 00
RSP: 0000:ffffc9000d533b08 EFLAGS: 00010046
RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000006
RDX: 0000000000000028 RSI: 00000000ffffffff RDI: 00000000ffffffff
RBP: ffff888107419680 R08: 0000000000000000 R09: ffffffff82d72b00
R10: 0000000000000000 R11: 0000000000000000 R12: 00000000000001ed
R13: 0000000000000000 R14: 00000000ffffffff R15: 0000000000000002
FS: 0000000000000000(0000) GS:ffff88bc8b500000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000000000000000 CR3: 0000000002610001 CR4: 00000000001706e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
? show_trace_log_lvl+0x1c1/0x2d9
? show_trace_log_lvl+0x1c1/0x2d9
? set_affinity_irq+0xdc/0x1c0
? __die_body.cold+0x8/0xd
? die+0x2b/0x50
? do_trap+0x90/0x110
? bind_evtchn_to_cpu+0xdf/0xf0
? do_error_trap+0x65/0x80
? bind_evtchn_to_cpu+0xdf/0xf0
? exc_invalid_op+0x4e/0x70
? bind_evtchn_to_cpu+0xdf/0xf0
? asm_exc_invalid_op+0x12/0x20
? bind_evtchn_to_cpu+0xdf/0x
---truncated---

En el kernel de Linux, se resolvió la siguiente vulnerabilidad: xen/events: cierre evtchn después de la limpieza del mapeo. Shutdown_pirq y startup_pirq no están tomando irq_mapping_update_lock porque no pueden hacerlo debido a la inversión de bloqueo. Ambos se llaman con el irq_desc-&gt;lock en curso. Sin embargo, el orden de bloqueo es primero irq_mapping_update_lock y luego irq_desc-&gt;lock. Esto abre múltiples ejecucións: - Shutdown_pirq puede ser interrumpido por una función que asigna un canal de evento: CPU0 CPU1 Shutdown_pirq { xen_evtchn_close(e) __startup_pirq { EVTCHNOP_bind_pirq -&gt; devuelve el evtchn e set_evtchn_to_irq(e, irq) recién liberado} xen_irq_info_cleanup() { set_evtchn_to_irq( e, -1) } } Supongamos que aquí el canal de eventos e se refiere aquí al mismo número de canal de eventos. Después de esta ejecución, el mapeo evtchn_to_irq para e no es válido (-1). - __startup_pirq compite con __unbind_from_irq de manera similar. Debido a que __startup_pirq no toma irq_mapping_update_lock, puede tomar el evtchn que __unbind_from_irq está liberando y limpiando actualmente. En este caso, aunque el canal de eventos esté asignado, su asignación se puede desarmar en evtchn_to_irq. La solución es limpiar primero las asignaciones y luego cerrar el canal de eventos. De esta manera, cuando se asigna un canal de eventos, se garantiza que sus posibles asignaciones anteriores de evtchn_to_irq ya no estarán configuradas. Este es también el orden inverso de la asignación donde primero se asigna el canal de evento y luego se configuran las asignaciones. En un kernel 5.10 antes de commit 3fcdaf3d7634 ("xen/events: modificar interfaces internas [un]bind"), encontramos un ERROR como el siguiente durante el sondeo de dispositivos NVMe. El problema es que durante nvme_setup_io_queues, se llama a pci_free_irq para cada dispositivo, lo que resulta en una llamada a Shutdown_pirq. Por lo tanto, con muchos dispositivos nvme es probable que alcance esta ejecución durante el arranque porque habrá múltiples llamadas a Shutdown_pirq y startup_pirq que se ejecutan potencialmente en paralelo. ------------[ cortar aquí ]------------ blkfront: xvda: barrera o descarga: deshabilitado; subvenciones persistentes: habilitadas; descriptores indirectos: habilitado; búfer de rebote: ¡ERROR del kernel habilitado en drivers/xen/events/events_base.c:499! código de operación no válido: 0000 [#1] SMP PTI CPU: 44 PID: 375 Comm: kworker/u257:23 No contaminado 5.10.201-191.748.amzn2.x86_64 #1 Nombre de hardware: Xen HVM domU, BIOS 4.11.amazon 24/08 /2006 Cola de trabajo: nvme-reset-wq nvme_reset_work RIP: 0010:bind_evtchn_to_cpu+0xdf/0xf0 Código: 5d 41 5e c3 cc cc cc cc 44 89 f7 e8 2b 55 ad ff 49 89 c5 48 85 c0 0f 84 64 ff ff ff 4c 8b 68 30 41 83 fe ff 0f 85 60 ff ff ff &lt;0f&gt; 0b 66 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 0f 1f 44 00 00 RSP: 0000:ffffc9000d533b08 EFLAGS: 00010046 RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000006 RDX: 0000000000000028 RSI: 00000000ffffffff RDI: 00000000ffffffff RBP: ffff888107419680 R08: 00000000000 00000 R09: ffffffff82d72b00 R10: 00000000000000000 R11: 0000000000000000 R12: 00000000000001ed R13: 00000000000000000 R14: 00000000ffffffff R15 : 0000000000000002 FS: 0000000000000000(0000) GS:ffff88bc8b500000( 0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00000000000000000 CR3: 0000000002610001 CR4: 000000000017 06e0 DR0: 0000000000000000 DR1: 00000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 Seguimiento de llamadas: ? show_trace_log_lvl+0x1c1/0x2d9? show_trace_log_lvl+0x1c1/0x2d9? set_affinity_irq+0xdc/0x1c0? __die_body.cold+0x8/0xd ? morir+0x2b/0x50 ? do_trap+0x90/0x110? bind_evtchn_to_cpu+0xdf/0xf0? do_error_trap+0x65/0x80? bind_evtchn_to_cpu+0xdf/0xf0? exc_invalid_op+0x4e/0x70? bind_evtchn_to_cpu+0xdf/0xf0? asm_exc_invalid_op+0x12/0x20? bind_evtchn_to_cpu+0xdf/0x ---truncado---

*Credits: N/A
CVSS Scores
Attack Vector
-
Attack Complexity
-
Privileges Required
-
User Interaction
-
Scope
-
Confidentiality
-
Integrity
-
Availability
-
* 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-14 EPSS Updated
  • 2024-09-11 CVE Updated
  • ---------- Exploited in Wild
  • ---------- KEV Due Date
  • ---------- First Exploit
CWE
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"
>= 2.6.37 < 5.4.274
Search vendor "Linux" for product "Linux Kernel" and version " >= 2.6.37 < 5.4.274"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 2.6.37 < 5.10.215
Search vendor "Linux" for product "Linux Kernel" and version " >= 2.6.37 < 5.10.215"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 2.6.37 < 5.15.154
Search vendor "Linux" for product "Linux Kernel" and version " >= 2.6.37 < 5.15.154"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 2.6.37 < 6.1.81
Search vendor "Linux" for product "Linux Kernel" and version " >= 2.6.37 < 6.1.81"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 2.6.37 < 6.6.19
Search vendor "Linux" for product "Linux Kernel" and version " >= 2.6.37 < 6.6.19"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 2.6.37 < 6.7.6
Search vendor "Linux" for product "Linux Kernel" and version " >= 2.6.37 < 6.7.6"
en
Affected
Linux
Search vendor "Linux"
Linux Kernel
Search vendor "Linux" for product "Linux Kernel"
>= 2.6.37 < 6.8
Search vendor "Linux" for product "Linux Kernel" and version " >= 2.6.37 < 6.8"
en
Affected