CVE-2022-49882

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
01/05/2025
Last modified:
02/05/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> KVM: Reject attempts to consume or refresh inactive gfn_to_pfn_cache<br /> <br /> Reject kvm_gpc_check() and kvm_gpc_refresh() if the cache is inactive.<br /> Not checking the active flag during refresh is particularly egregious, as<br /> KVM can end up with a valid, inactive cache, which can lead to a variety<br /> of use-after-free bugs, e.g. consuming a NULL kernel pointer or missing<br /> an mmu_notifier invalidation due to the cache not being on the list of<br /> gfns to invalidate.<br /> <br /> Note, "active" needs to be set if and only if the cache is on the list<br /> of caches, i.e. is reachable via mmu_notifier events. If a relevant<br /> mmu_notifier event occurs while the cache is "active" but not on the<br /> list, KVM will not acquire the cache&amp;#39;s lock and so will not serailize<br /> the mmu_notifier event with active users and/or kvm_gpc_refresh().<br /> <br /> A race between KVM_XEN_ATTR_TYPE_SHARED_INFO and KVM_XEN_HVM_EVTCHN_SEND<br /> can be exploited to trigger the bug.<br /> <br /> 1. Deactivate shinfo cache:<br /> <br /> kvm_xen_hvm_set_attr<br /> case KVM_XEN_ATTR_TYPE_SHARED_INFO<br /> kvm_gpc_deactivate<br /> kvm_gpc_unmap<br /> gpc-&gt;valid = false<br /> gpc-&gt;khva = NULL<br /> gpc-&gt;active = false<br /> <br /> Result: active = false, valid = false<br /> <br /> 2. Cause cache refresh:<br /> <br /> kvm_arch_vm_ioctl<br /> case KVM_XEN_HVM_EVTCHN_SEND<br /> kvm_xen_hvm_evtchn_send<br /> kvm_xen_set_evtchn<br /> kvm_xen_set_evtchn_fast<br /> kvm_gpc_check<br /> return -EWOULDBLOCK because !gpc-&gt;valid<br /> kvm_xen_set_evtchn_fast<br /> return -EWOULDBLOCK<br /> kvm_gpc_refresh<br /> hva_to_pfn_retry<br /> gpc-&gt;valid = true<br /> gpc-&gt;khva = not NULL<br /> <br /> Result: active = false, valid = true<br /> <br /> 3. Race ioctl KVM_XEN_HVM_EVTCHN_SEND against ioctl<br /> KVM_XEN_ATTR_TYPE_SHARED_INFO:<br /> <br /> kvm_arch_vm_ioctl<br /> case KVM_XEN_HVM_EVTCHN_SEND<br /> kvm_xen_hvm_evtchn_send<br /> kvm_xen_set_evtchn<br /> kvm_xen_set_evtchn_fast<br /> read_lock gpc-&gt;lock<br /> kvm_xen_hvm_set_attr case<br /> KVM_XEN_ATTR_TYPE_SHARED_INFO<br /> mutex_lock kvm-&gt;lock<br /> kvm_xen_shared_info_init<br /> kvm_gpc_activate<br /> gpc-&gt;khva = NULL<br /> kvm_gpc_check<br /> [ Check passes because gpc-&gt;valid is<br /> still true, even though gpc-&gt;khva<br /> is already NULL. ]<br /> shinfo = gpc-&gt;khva<br /> pending_bits = shinfo-&gt;evtchn_pending<br /> CRASH: test_and_set_bit(..., pending_bits)

Impact