CVE-2026-98468 in Linux
Сводка
по VulDB • 19.10.2026
В ядре Linux была устранена следующая уязвимость:
KVM: arm64: исправление ложного предупреждения о гонке при безобидном разборе stage 2 (stage 2 teardown race)
Для создания виртуальной машины L1 с 8 процессорами и 8 ГБ ОЗУ, виртуальной машины L2 с 4 процессорами и 4 ГБ ОЗУ и виртуальной машины L3 с 2 процессорами и 2 ГБ ОЗУ использовался kvmtool; все они затем были завершены.
В условиях дефицита памяти на хосте уровня L0 наблюдались предупреждения, вызванные миграцией, инициированной уплотнением (compaction):
WARNING: arch/arm64/kvm/mmu.c:336 at __unmap_stage2_range+0x64/0x80, CPU#5: kcompactd0/66
Которые, в свою очередь, были вызваны уведомителем MMU (MMU notifier) для инвалидации хоста:
mmu_notifier_invalidate_range_start() -> ... -> kvm_mmu_notifier_invalidate_range_start() -> kvm_mmu_unmap_gfn_range() -> kvm_unmap_gfn_range() -> kvm_nested_s2_unmap() -> kvm_stage2_unmap_range() -> __unmap_stage2_range() -> stage2_apply_range() <- -EINVAL, вызывающий WARN_ON()
Гонка с разбором таблиц страниц уровня 2 (stage 2) на уровне L0:
exit_mm() -> mmput() -> __mmput() -> exit_mmap() -> mmu_notifier_release() -> ... -> kvm_mmu_notifier_release() -> kvm_flush_shadow_all() -> kvm_arch_flush_shadow_all() -> kvm_free_stage2_pgd() -> [ получение блокировки kvm->mmu_lock для записи ]
-> mmu->pgt = NULL [ среди других задач ]
-> [ освобождение блокировки kvm->mmu_lock для записи ]
Выяснилось, что существует безобидная гонка (benign race), приводящая к ложному предупреждению:
Поток A - уведомление: миграция | Поток B - уведомление: релиз -------------------------------|--------------------------------- < kvm->mmu_lock удерживается > | stage2_apply_range() | get mmu->pgt, проверка !NULL | ... | kvm_arch_flush_shadow_all() cond_resched_rwlock_write(); | < конкуренция, ожидание блокировки kvm->mmu_lock > < освобождение kvm->mmu_lock > | < получение блокировки kvm->mmu_lock> | ... | kvm_free_stage2_pgd() | mmu->pgt = NULL | < инвалидация MMU > | ... | < освобождение блокировки kvm->mmu_lock > [ запланировано выполнение ] |
stage2_apply_range() | < цикл к следующей итерации > | get, mmu->pgt, проверка !NULL | is NULL, return -EINVAL | __unmap_stage2_range() | WARN_ON(-EINVAL) <--- совершенно ложное — гонка была обработана корректно.
Исправление заключается в устранении ложного предупреждения путем обновления функции stage2_apply_range(), чтобы она больше не рассматривала одновременный разбор PGT (page global directory) при освобождении блокировки как ошибку — независимо от того, разбирает ли обходчик таблицы страниц или выполняет другие действия, это является законной причиной для прерывания операции без возникновения ошибки.
Это сохраняет наличие предупреждения во всех остальных случаях.
На практике только функция __unmap_stage2_range() фактически обрабатывает эту ошибку, поэтому изменение затрагивает лишь её.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.