PT-2026-51863 · Linux · Linux
Publicado
2026-06-24
·
Atualizado
2026-06-24
·
CVE-2026-52969
Nenhuma
Não há classificações de severidade ou métricas disponíveis. Quando houver, atualizaremos as informações correspondentes na página.
In the Linux kernel, the following vulnerability has been resolved:
KVM: Reject wrapped offset in kvm reset dirty gfn()
kvm reset dirty gfn() guards the gfn range with
if (!memslot || (offset + fls(mask)) >= memslot->npages)
return;but offset is u64 and the addition is unchecked. The check can be
silently bypassed by a u64 wrap.
The dirty ring backing those entries is MAP SHARED at
KVM DIRTY LOG PAGE OFFSET of the vcpu fd, so the VMM can rewrite the
slot and offset fields of any entry between when the kernel pushes
them and when KVM RESET DIRTY RINGS consumes them. On reset,
kvm dirty ring reset() re-reads the values via READ ONCE() and feeds
them straight back into this check; only the flags handshake is
treated as the handover, the slot/offset payload is taken on trust.
Crafting two entries
entry[i].offset = 0xffffffffffffffc1
entry[i+1].offset = 0makes the coalescing loop in kvm dirty ring reset() compute
delta = (s64)(0 - 0xffffffffffffffc1) = 63which falls in [0, BITS PER LONG), so it folds entry[i+1] into the
existing mask by setting bit 63. The trailing kvm reset dirty gfn()
call then sees offset = 0xffffffffffffffc1 and fls(mask) = 63;
the sum is 0 in u64 and the bounds check passes.
That offset propagates into kvm arch mmu enable log dirty pt masked()
unchanged. On the legacy MMU path -- kvm memslots have rmaps() ==
true, i.e. shadow paging, any VM that has allocated shadow roots, or
a write-tracked slot -- it reaches gfn to rmap(), which indexes
slot->arch.rmap[0][] with a near-U64 MAX gfn. That is an
out-of-bounds load of a kvm rmap head, followed by a conditional
clear of PT WRITABLE MASK in whatever the loaded pointer points at.
The path is reachable from any process holding /dev/kvm.
Range-check offset on its own first, so the addition cannot wrap.
memslot->npages is bounded well below U64 MAX, so once offset <
npages holds, offset + fls(mask) (with fls(mask) < BITS PER LONG)
stays in range.
Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾
Identificadores relacionados
Produtos afetados
Linux