2025-03-09 03:03:50 +00:00

72 lines
5.9 KiB
JSON

{
"id": "CVE-2021-47639",
"sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
"published": "2025-02-26T06:37:05.677",
"lastModified": "2025-02-27T19:15:40.773",
"vulnStatus": "Awaiting Analysis",
"cveTags": [],
"descriptions": [
{
"lang": "en",
"value": "In the Linux kernel, the following vulnerability has been resolved:\n\nKVM: x86/mmu: Zap _all_ roots when unmapping gfn range in TDP MMU\n\nZap both valid and invalid roots when zapping/unmapping a gfn range, as\nKVM must ensure it holds no references to the freed page after returning\nfrom the unmap operation. Most notably, the TDP MMU doesn't zap invalid\nroots in mmu_notifier callbacks. This leads to use-after-free and other\nissues if the mmu_notifier runs to completion while an invalid root\nzapper yields as KVM fails to honor the requirement that there must be\n_no_ references to the page after the mmu_notifier returns.\n\nThe bug is most easily reproduced by hacking KVM to cause a collision\nbetween set_nx_huge_pages() and kvm_mmu_notifier_release(), but the bug\nexists between kvm_mmu_notifier_invalidate_range_start() and memslot\nupdates as well. Invalidating a root ensures pages aren't accessible by\nthe guest, and KVM won't read or write page data itself, but KVM will\ntrigger e.g. kvm_set_pfn_dirty() when zapping SPTEs, and thus completing\na zap of an invalid root _after_ the mmu_notifier returns is fatal.\n\n WARNING: CPU: 24 PID: 1496 at arch/x86/kvm/../../../virt/kvm/kvm_main.c:173 [kvm]\n RIP: 0010:kvm_is_zone_device_pfn+0x96/0xa0 [kvm]\n Call Trace:\n <TASK>\n kvm_set_pfn_dirty+0xa8/0xe0 [kvm]\n __handle_changed_spte+0x2ab/0x5e0 [kvm]\n __handle_changed_spte+0x2ab/0x5e0 [kvm]\n __handle_changed_spte+0x2ab/0x5e0 [kvm]\n zap_gfn_range+0x1f3/0x310 [kvm]\n kvm_tdp_mmu_zap_invalidated_roots+0x50/0x90 [kvm]\n kvm_mmu_zap_all_fast+0x177/0x1a0 [kvm]\n set_nx_huge_pages+0xb4/0x190 [kvm]\n param_attr_store+0x70/0x100\n module_attr_store+0x19/0x30\n kernfs_fop_write_iter+0x119/0x1b0\n new_sync_write+0x11c/0x1b0\n vfs_write+0x1cc/0x270\n ksys_write+0x5f/0xe0\n do_syscall_64+0x38/0xc0\n entry_SYSCALL_64_after_hwframe+0x44/0xae\n </TASK>"
},
{
"lang": "es",
"value": "En el kernel de Linux, se ha resuelto la siguiente vulnerabilidad: KVM: x86/mmu: Se eliminan _todos_ las ra\u00edces al anular la asignaci\u00f3n del rango gfn en TDP MMU Se eliminan las ra\u00edces v\u00e1lidas e inv\u00e1lidas al hacer zapping/anular la asignaci\u00f3n de un rango gfn, ya que KVM debe asegurarse de que no contiene referencias a la p\u00e1gina liberada despu\u00e9s de regresar de la operaci\u00f3n de anulaci\u00f3n de la asignaci\u00f3n. En particular, TDP MMU no elimina las ra\u00edces inv\u00e1lidas en las devoluciones de llamadas mmu_notifier. Esto conduce a problemas de use-after-free y otros problemas si mmu_notifier se ejecuta hasta el final mientras que un zapper de ra\u00edz inv\u00e1lida cede, ya que KVM no cumple con el requisito de que no debe haber _ninguna_ referencia a la p\u00e1gina despu\u00e9s de que mmu_notifier regrese. El error se reproduce m\u00e1s f\u00e1cilmente pirateando KVM para provocar una colisi\u00f3n entre set_nx_huge_pages() y kvm_mmu_notifier_release(), pero el error tambi\u00e9n existe entre kvm_mmu_notifier_invalidate_range_start() y las actualizaciones de memslot. Invalidar una ra\u00edz garantiza que el invitado no pueda acceder a las p\u00e1ginas, y KVM no leer\u00e1 ni escribir\u00e1 datos de p\u00e1gina por s\u00ed mismo, pero KVM activar\u00e1, por ejemplo, kvm_set_pfn_dirty() al hacer zapping de SPTE, y por lo tanto, completar un zapping de una ra\u00edz no v\u00e1lida _despu\u00e9s_ de que mmu_notifier regrese es fatal. ADVERTENCIA: CPU: 24 PID: 1496 en arch/x86/kvm/../../../virt/kvm/kvm_main.c:173 [kvm] RIP: 0010:kvm_is_zone_device_pfn+0x96/0xa0 [kvm] Rastreo de llamadas: kvm_set_pfn_dirty+0xa8/0xe0 [kvm] __handle_changed_spte+0x2ab/0x5e0 [kvm] __handle_changed_spte+0x2ab/0x5e0 [kvm] __handle_changed_spte+0x2ab/0x5e0 [kvm] zap_gfn_range+0x1f3/0x310 [kvm] kvm_tdp_mmu_zap_ra\u00edces_invalidadas+0x50/0x90 [kvm] kvm_mmu_zap_all_fast+0x177/0x1a0 [kvm] set_nx_huge_pages+0xb4/0x190 [kvm] param_attr_store+0x70/0x100 module_attr_store+0x19/0x30 kernfs_fop_write_iter+0x119/0x1b0 new_sync_write+0x11c/0x1b0 vfs_write+0x1cc/0x270 ksys_write+0x5f/0xe0 do_syscall_64+0x38/0xc0 entry_SYSCALL_64_after_hwframe+0x44/0xae "
}
],
"metrics": {
"cvssMetricV31": [
{
"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"type": "Secondary",
"cvssData": {
"version": "3.1",
"vectorString": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
"baseScore": 7.8,
"baseSeverity": "HIGH",
"attackVector": "LOCAL",
"attackComplexity": "LOW",
"privilegesRequired": "LOW",
"userInteraction": "NONE",
"scope": "UNCHANGED",
"confidentialityImpact": "HIGH",
"integrityImpact": "HIGH",
"availabilityImpact": "HIGH"
},
"exploitabilityScore": 1.8,
"impactScore": 5.9
}
]
},
"weaknesses": [
{
"source": "134c704f-9b21-4f2e-91b3-4a467353bcc0",
"type": "Secondary",
"description": [
{
"lang": "en",
"value": "CWE-416"
}
]
}
],
"references": [
{
"url": "https://git.kernel.org/stable/c/0c8a8da182d4333d9bbb9131d765145568c847b2",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
},
{
"url": "https://git.kernel.org/stable/c/8cf6f98ab1d16d5e607635a0c21c4231eb15367e",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
},
{
"url": "https://git.kernel.org/stable/c/af47248407c0c5ae52a752af1ab5ce5b0db91502",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
},
{
"url": "https://git.kernel.org/stable/c/d62007edf01f5c11f75d0f4b1e538fc52a5b1982",
"source": "416baaa9-dc9f-4396-8d5f-8c081fb06d67"
}
]
}