NONE

CVE-2026-23198

Обновлено 14 февраля 2026

В ядре Linux устранена следующая уязвимость: KVM: не затирать тип маршрутизации irqfd при отмене назначения irqfd При отмене назначения KVM_IRQFD не удаляйте копию IRQ, принадлежащую irqfd. запись маршрутизации, поскольку при этом нарушается kvm_arch_irq_bypass_del_producer() на x86 и Arm64, которые явно ищут KVM_IRQ_ROUTING_MSI. Вместо этого, чтобы обработать одновременное обновление маршрутизации, убедиться, что irqfd все еще активен перед использованием информации о маршрутизации. Как показывают x86 и ошибки Arm64 и еще одна ошибка в kvm_arch_update_irqfd_routing() (см. ниже), удаление типа записи без уведомления кода арки удивительно и склонен к ошибкам. В качестве бонуса проверка активности irqfd обеспечивает удобный место для документирования _почему_ KVM не должен использовать запись маршрутизации для irqfd, который находится в процессе отмены назначения: как только irqfd будет удален из списка (что происходит *до* отсоединения eventfd), он больше не будет получать обновления через kvm_irq_routing_update(), поэтому KVM может доставить событие, используя устаревшую информацию о маршрутизации (относительно KVM_SET_GSI_ROUTING возвращается в пространство пользователя). В качестве еще лучшего бонуса — явная проверка активности irqfd. исправляет ошибку, аналогичную той, которую пытается предотвратить затирание: если irqfd деактивируется, а затем меняется его маршрутизация, kvm_irq_routing_update() не будет вызывать kvm_arch_update_irqfd_routing() (потому что irqfd нет в списке). Итак, если irqfd находится в обходе режиме, IRQ будут по-прежнему отправляться с использованием старой информации о маршрутизации. Что касается kvm_arch_irq_bypass_del_producer(), затирание типа маршрутизации приводит к тому, что KVM неправильно удерживает IRQ в режиме обхода, что особенно проблематично для AMD, поскольку KVM отслеживает IRQ, отправляемые на виртуальный ЦП в списке, время жизни которого привязано к irqfd. Без помощи КАСАН для обнаружения использования после бесплатного использования наиболее распространенный Sympton на AMD — это разыменование NULL-указателя в amd_iommu_update_ga() из-за память для структуры irqfd перераспределяется и обнуляется, в результате в irqfd->irq_bypass_data значение NULL при чтении avic_update_iommu_vcpu_affinity(): ОШИБКА: разыменование нулевого указателя ядра, адрес: 0000000000000018. #PF: доступ супервизора на чтение в режиме ядра #PF: код_ошибки(0x0000) — страница отсутствует PGD 40cf2b9067 P4D 40cf2b9067 PUD 408362a067 PMD 0 Упс: Упс: 0000 [#1] SMP ЦП: 6 UID: 0 PID: 40383 Связь: vfio_irq_test Испорчено: G U W O 6.19.0-smp--5dddc257e6b2-irqfd #31 НЕТ Испорчено: [U]=ПОЛЬЗОВАТЕЛЬ, [W]=ПРЕДУПРЕЖДЕНИЕ, [O]=OOT_MODULE Название оборудования: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 34.78.2-0 05.09.2025 RIP: 0010:amd_iommu_update_ga+0x19/0xe0 Отслеживание вызова: <ЗАДАЧА> avic_update_iommu_vcpu_affinity+0x3d/0x90 [kvm_amd] __avic_vcpu_load+0xf4/0x130 [kvm_amd] kvm_arch_vcpu_load+0x89/0x210 [квм] vcpu_load+0x30/0x40 [квм] kvm_arch_vcpu_ioctl_run+0x45/0x620 [kvm] kvm_vcpu_ioctl+0x571/0x6a0 [квм] __se_sys_ioctl+0x6d/0xb0 do_syscall_64+0x6f/0x9d0 запись_SYSCALL_64_after_hwframe+0x4b/0x53 РИП: 0033:0x46893b </TASK> ---[ конечная трассировка 0000000000000000 ]--- Если AVIC заблокирован при отмене назначения irfd, ошибка проявится как повреждение списка, например о следующем задании irqfd. list_add повреждение. следующий->предыдущий должен быть предыдущим (ffff8d474d5cd588), но было 0000000000000000. (next=ffff8d8658f86530). ------------[вырезать здесь]------------ ОШИБКА ядра в lib/list_debug.c:31! К сожалению: неверный код операции: 0000 [#1] SMP ЦП: 128 UID: 0 PID: 80818 Связь: vfio_irq_test Испорчено: G U W O 6.19.0-smp--f19dc4d680ba-irqfd #28 НЕТ Испорчено: [U]=ПОЛЬЗОВАТЕЛЬ, [W]=ПРЕДУПРЕЖДЕНИЕ, [O]=OOT_MODULE Название оборудования: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 34.78.2-0 05.09.2025 RIP: 0010:__list_add_valid_or_report+0x97/0xc0 Отслеживание вызова: <ЗАДАЧА> avic_pi_update_irte+0x28e/0x2b0 [kvm_amd] kvm_pi_update_irte+0xbf/0x190 [квм] kvm_arch_irq_bypass_add_producer+0x72/0x90 [kvm] irq_bypass_register_consumer+0xcd/0x170 [irqbypa ---усечено---

Показать оригинальное описание (английский)

In the Linux kernel, the following vulnerability has been resolved: KVM: Don't clobber irqfd routing type when deassigning irqfd When deassigning a KVM_IRQFD, don't clobber the irqfd's copy of the IRQ's routing entry as doing so breaks kvm_arch_irq_bypass_del_producer() on x86 and arm64, which explicitly look for KVM_IRQ_ROUTING_MSI. Instead, to handle a concurrent routing update, verify that the irqfd is still active before consuming the routing information. As evidenced by the x86 and arm64 bugs, and another bug in kvm_arch_update_irqfd_routing() (see below), clobbering the entry type without notifying arch code is surprising and error prone. As a bonus, checking that the irqfd is active provides a convenient location for documenting _why_ KVM must not consume the routing entry for an irqfd that is in the process of being deassigned: once the irqfd is deleted from the list (which happens *before* the eventfd is detached), it will no longer receive updates via kvm_irq_routing_update(), and so KVM could deliver an event using stale routing information (relative to KVM_SET_GSI_ROUTING returning to userspace). As an even better bonus, explicitly checking for the irqfd being active fixes a similar bug to the one the clobbering is trying to prevent: if an irqfd is deactivated, and then its routing is changed, kvm_irq_routing_update() won't invoke kvm_arch_update_irqfd_routing() (because the irqfd isn't in the list). And so if the irqfd is in bypass mode, IRQs will continue to be posted using the old routing information. As for kvm_arch_irq_bypass_del_producer(), clobbering the routing type results in KVM incorrectly keeping the IRQ in bypass mode, which is especially problematic on AMD as KVM tracks IRQs that are being posted to a vCPU in a list whose lifetime is tied to the irqfd. Without the help of KASAN to detect use-after-free, the most common sympton on AMD is a NULL pointer deref in amd_iommu_update_ga() due to the memory for irqfd structure being re-allocated and zeroed, resulting in irqfd->irq_bypass_data being NULL when read by avic_update_iommu_vcpu_affinity(): BUG: kernel NULL pointer dereference, address: 0000000000000018 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 40cf2b9067 P4D 40cf2b9067 PUD 408362a067 PMD 0 Oops: Oops: 0000 [#1] SMP CPU: 6 UID: 0 PID: 40383 Comm: vfio_irq_test Tainted: G U W O 6.19.0-smp--5dddc257e6b2-irqfd #31 NONE Tainted: [U]=USER, [W]=WARN, [O]=OOT_MODULE Hardware name: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 34.78.2-0 09/05/2025 RIP: 0010:amd_iommu_update_ga+0x19/0xe0 Call Trace: <TASK> avic_update_iommu_vcpu_affinity+0x3d/0x90 [kvm_amd] __avic_vcpu_load+0xf4/0x130 [kvm_amd] kvm_arch_vcpu_load+0x89/0x210 [kvm] vcpu_load+0x30/0x40 [kvm] kvm_arch_vcpu_ioctl_run+0x45/0x620 [kvm] kvm_vcpu_ioctl+0x571/0x6a0 [kvm] __se_sys_ioctl+0x6d/0xb0 do_syscall_64+0x6f/0x9d0 entry_SYSCALL_64_after_hwframe+0x4b/0x53 RIP: 0033:0x46893b </TASK> ---[ end trace 0000000000000000 ]--- If AVIC is inhibited when the irfd is deassigned, the bug will manifest as list corruption, e.g. on the next irqfd assignment. list_add corruption. next->prev should be prev (ffff8d474d5cd588), but was 0000000000000000. (next=ffff8d8658f86530). ------------[ cut here ]------------ kernel BUG at lib/list_debug.c:31! Oops: invalid opcode: 0000 [#1] SMP CPU: 128 UID: 0 PID: 80818 Comm: vfio_irq_test Tainted: G U W O 6.19.0-smp--f19dc4d680ba-irqfd #28 NONE Tainted: [U]=USER, [W]=WARN, [O]=OOT_MODULE Hardware name: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 34.78.2-0 09/05/2025 RIP: 0010:__list_add_valid_or_report+0x97/0xc0 Call Trace: <TASK> avic_pi_update_irte+0x28e/0x2b0 [kvm_amd] kvm_pi_update_irte+0xbf/0x190 [kvm] kvm_arch_irq_bypass_add_producer+0x72/0x90 [kvm] irq_bypass_register_consumer+0xcd/0x170 [irqbypa ---truncated---