U.S. flag   An official website of the United States government
Dot gov

Official websites use .gov
A .gov website belongs to an official government organization in the United States.

Https

Secure .gov websites use HTTPS
A lock (Dot gov) or https:// means you've safely connected to the .gov website. Share sensitive information only on official, secure websites.

Vulnerability Change Records for CVE-2026-52969

Change History

New CVE Received from kernel.org 6/24/2026 1:17:07 PM

Action Type Old Value New Value
Added Description

                  
                
              
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 = 0

makes the coalescing loop in kvm_dirty_ring_reset() compute

	delta = (s64)(0 - 0xffffffffffffffc1) = 63

which 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.
Added Reference

                  
                
              
https://git.kernel.org/stable/c/01b71b930f15728aa8599478a7ce90c19dcd9fc2
Added Reference

                  
                
              
https://git.kernel.org/stable/c/0d419c23bb11b5c9664de777c47c1f04a235882d
Added Reference

                  
                
              
https://git.kernel.org/stable/c/0eb281eb95b2d4eea4db1da5fe91023aecc97095
Added Reference

                  
                
              
https://git.kernel.org/stable/c/577a8d3bae0531f0e5ccfac919cd8192f920a804
Added Reference

                  
                
              
https://git.kernel.org/stable/c/74f1a22f7a80f03d28ad8551a2d25d563433addf
Added Reference

                  
                
              
https://git.kernel.org/stable/c/b315b033a877b1ee6d827810b5d7bb4392ffcf8d
Added Reference

                  
                
              
https://git.kernel.org/stable/c/ecf9b3ea7847fe14f34b8c41f00de1eb95c747da
Added Affected

                  
                
              
[{"vendor":"Linux","product":"Linux","defaultStatus":"unaffected","programFiles":["virt/kvm/dirty_ring.c"],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","versions":[{"version":"fb04a1eddb1a65b6588a021bdc132270d5ae48bb","lessThan":"74f1a22f7a80f03d28ad8551a2d25d563433addf","versionType":"git","status":"affected"},{"version":"fb04a1eddb1a65b6588a021bdc132270d5ae48bb","lessThan":"0eb281eb95b2d4eea4db1da5fe91023aecc97095","versionType":"git","status":"affected"},{"version":"fb04a1eddb1a65b6588a021bdc132270d5ae48bb","lessThan":"01b71b930f15728aa8599478a7ce90c19dcd9fc2","versionType":"git","status":"affected"},{"version":"fb04a1eddb1a65b6588a021bdc132270d5ae48bb","lessThan":"b315b033a877b1ee6d827810b5d7bb4392ffcf8d","versionType":"git","status":"affected"},{"version":"fb04a1eddb1a65b6588a021bdc132270d5ae48bb","lessThan":"0d419c23bb11b5c9664de777c47c1f04a235882d","versionType":"git","status":"affected"},{"version":"fb04a1eddb1a65b6588a021bdc132270d5ae48bb","lessThan":"ecf9b3ea7847fe14f34b8c41f00de1eb95c747da","versionType":"git","status":"affected"},{"version":"fb04a1eddb1a65b6588a021bdc132270d5ae48bb","lessThan":"577a8d3bae0531f0e5ccfac919cd8192f920a804","versionType":"git","status":"affected"}]},{"vendor":"Linux","product":"Linux","defaultStatus":"affected","programFiles":["virt/kvm/dirty_ring.c"],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","versions":[{"version":"5.11","status":"affected"},{"version":"0","lessThan":"5.11","versionType":"semver","status":"unaffected"},{"version":"5.15.209","lessThanOrEqual":"5.15.*","versionType":"semver","status":"unaffected"},{"version":"6.1.175","lessThanOrEqual":"6.1.*","versionType":"semver","status":"unaffected"},{"version":"6.6.141","lessThanOrEqual":"6.6.*","versionType":"semver","status":"unaffected"},{"version":"6.12.91","lessThanOrEqual":"6.12.*","versionType":"semver","status":"unaffected"},{"version":"6.18.33","lessThanOrEqual":"6.18.*","versionType":"semver","status":"unaffected"},{"version":"7.0.10","lessThanOrEqual":"7.0.*","versionType":"semver","status":"unaffected"},{"version":"7.1","lessThanOrEqual":"*","versionType":"original_commit_for_fix","status":"unaffected"}]}]