Public bug reported:
=== SUMMARY ===
On 2026-10-29 this machine panicked twice within ~2h40m, in two different
mm/swap code paths, both times while the kernel was consuming a PTE that
decodes as a swap entry but is not backed by a valid swap_info entry:
crash #1 19:27:36 fork path -> dup_mmap -> copy_nonpresent_pte
-> swap_dup_entry_direct -> __swap_duplicate
-> _raw_spin_lock on a bogus address
crash #2 22:09:05 exit path -> exit_mmap -> zap_pte_range
-> zap_nonpresent_ptes -> swap_pte_batch
-> lookup_swap_cgroup_id on a bogus map
The second stack is exactly the path described in CVE-2026-64416
("mm: swap_cgroup: fix NULL deref in lookup_swap_cgroup_id on swapless host",
upstream 63b02a9409cb): swap_pte_batch() feeds any PTE that decodes as a
type-0 swap entry to lookup_swap_cgroup_id() without validating it against
swap_info[].
Ubuntu's tracker lists CVE-2026-64416 as fixed in 7.0.0-31.31, and
linux-image-generic here is 7.0.0-42.42, yet the same class of failure still
reproduces on this host. Reporting in case the fix is incomplete or was lost
in a rebase.
The user-visible symptom was "the machine rebooted when I closed Chrome".
That is the trigger, not the cause: closing Chrome makes the Chrome process
group exit, which runs exit_mmap(), which walks the page tables and trips
over the bad entry.
=== ENVIRONMENT ===
Kernel : 7.0.0-42-generic #42-Ubuntu (PREEMPT(lazy), SMP NOPTI)
Package : linux-image-generic 7.0.0-42.42 (resolute-updates)
also available: 7.0.0-38.38 (resolute-security), 7.0.0-14.14
Release : Ubuntu Desktop 26.04.1 LTS
Hardware : LENOVO 20TA002CUS (ThinkPad E14 Gen2), i5-1135G7, 16 GB RAM,
256 GB NVMe
BIOS : R1EET67W(1.67) 04/20/2026 (latest available)
Microcode : 0xbe (from 0x86)
Swap : /swap.img, 4 GiB, enabled in /etc/fstab
usage was 0 kB before both crashes (sar -S, 21:30-22:00)
kdump : enabled (USE_KDUMP=1), vmcore captured for crash #2
Tainted : crash #1 "Not tainted"
crash #2 "G I" ([I] = FIRMWARE_WORKAROUND only)
=== CRASH #1 — 2026-10-29 19:27:36, task gly-hdl-loader ===
[ 4885.940349] BUG: unable to handle page fault for address: ffffc9f086bafbe0
[ 4885.940365] #PF: supervisor write access in kernel mode
[ 4885.940370] #PF: error_code(0x0002) - not-present page
[ 4885.940374] PGD 0 P4D 0
[ 4885.940380] Oops: Oops: 0002 [#1] SMP NOPTI
[ 4885.940389] CPU: 0 UID: 1000 PID: 12487 Comm: gly-hdl-loader Kdump: loaded
Not tainted 7.0.0-42-generic #42-Ubuntu PREEMPT(lazy)
[ 4885.940400] RIP: 0010:_raw_spin_lock+0x13/0x60
[ 4885.940429] RDX: 0000000000000001 RSI: 0000000000000001 RDI: ffffc9f086bafbe0
[ 4885.940436] R10: 0000000000000000 R11: 0000000000000000 R12: ffffc9f086bafbe0
[ 4885.940439] R13: 0000000000000001 R14: ffff89f08031ac00 R15: 0000000000800000
[ 4885.940452] CR2: ffffc9f086bafbe0 CR3: 0000000141cc8005
[ 4885.940459] Call Trace:
[ 4885.940463] <TASK>
[ 4885.940466] ? __swap_duplicate.constprop.0+0x69/0x1c0
[ 4885.940479] swap_dup_entry_direct+0x1c/0x60
[ 4885.940485] copy_nonpresent_pte+0x12b/0x7d0
[ 4885.940493] copy_pte_range+0x446/0x5d0
[ 4885.940501] copy_p4d_range+0x3d8/0x560
[ 4885.940511] copy_page_range+0x199/0x2e0
[ 4885.940520] dup_mmap+0x387/0x870
[ 4885.940531] dup_mm.constprop.0+0x6f/0x170
[ 4885.940543] copy_process+0x15d6/0x1760
[ 4885.940556] kernel_clone+0xb6/0x4c0
[ 4885.940578] __do_sys_clone+0x68/0xa0
[ 4885.940588] __x64_sys_clone+0x25/0x40
[ 4885.940604] do_syscall_64+0x105/0x580
[ 4885.940767] entry_SYSCALL_64_after_hwframe+0x76/0x7e
RDI/R12 = ffffc9f086bafbe0 is a vmalloc-range address that is not mapped
("PGD 0 P4D 0"); _raw_spin_lock tries to write to it. This is a stale or
never-initialised pointer, not the pointer of a live lock.
Note: the same task was simply calling clone(2); the bad entry belongs to the
parent's page tables and was copied by copy_nonpresent_pte().
=== CRASH #2 — 2026-10-29 22:09:05, task MemoryInfra (Chrome) ===
[ 3535.840787] Oops: general protection fault, probably for non-canonical
address 0x7d27282a38ffc: 0000 [#1] SMP NOPTI
[ 3535.840799] CPU: 6 UID: 1000 PID: 6457 Comm: MemoryInfra Kdump: loaded
Tainted: G I 7.0.0-42-generic #42-Ubuntu PREEMPT(lazy)
[ 3535.840805] Tainted: [I]=FIRMWARE_WORKAROUND
[ 3535.840806] Hardware name: LENOVO 20TA002CUS/20TA002CUS, BIOS R1EET67W(1.67
) 04/20/2026
[ 3535.840809] RIP: 0010:lookup_swap_cgroup_id+0x49/0xa0
[ 3535.840816] Code: 48 8b 04 c5 40 a0 5f ab 48 85 c0 74 3e 48 ba ff ff ff
ff ff ff ff 03 48 21 d1 48 89 ca 83 e1 01 48 d1 ea c1 e1 04
48 8d 04 90 <8b> 00 c9 d3 e8 ...
[ 3535.840823] RAX: 0007d27282a38ffc RBX: 00000000007ffe00 RCX: 0000000000000010
[ 3535.840826] RDX: 0001ffffffffdfff RSI: 0000000000000000 RDI: 0003ffffffffbfff
[ 3535.840829] R10: 000000000000001e R11: 0000000000000000 R12: ffff8e4846388000
[ 3535.840831] R13: 0000000000800000 R14: ffff8e4846387870 R15: ffff8e4846387878
[ 3535.840842] Call Trace:
[ 3535.840844] <TASK>
[ 3535.840847] ? softleaf_from_pte+0x83/0xb0
[ 3535.840853] swap_pte_batch+0xa7/0x2a0
[ 3535.840856] zap_nonpresent_ptes.constprop.0.isra.0+0x497/0x520
[ 3535.840860] zap_pte_range+0x321/0x780
[ 3535.840864] zap_pmd_range.isra.0+0xce/0x250
[ 3535.840868] unmap_page_range+0x23a/0x3d0
[ 3535.840872] unmap_single_vma+0x96/0x110
[ 3535.840875] unmap_vmas+0xa5/0x180
[ 3535.840880] exit_mmap+0x13b/0x400
[ 3535.840888] __mmput+0x45/0x170
[ 3535.840893] mmput+0x31/0x40
[ 3535.840897] exit_mm+0xe3/0x150
[ 3535.840901] do_exit+0x1e4/0x4b0
[ 3535.840904] do_group_exit+0x2d/0xb0
[ 3535.840908] get_signal+0x7f5/0x830
[ 3535.840912] arch_do_signal_or_restart+0x36/0x110
[ 3535.840918] exit_to_user_mode_loop+0x8f/0x540
[ 3535.840924] do_syscall_64+0x22f/0x580
The faulting access is the load at lookup_swap_cgroup_id+0x49, i.e. the
ctrl->map dereference inside __swap_cgroup_id_lookup(). RAX (the computed
address) = 0x0007d27282a38ffc — 13 leading zero bits, hence non-canonical and
reported as a #GP. That is the classic shape of "base pointer is junk, offset
is small": the array element read from swap_cgroup_ctrl[type].map was not a
valid pointer (or the type index was garbage).
Userspace side: the task was in futex(), got a signal and was exiting. The
machine had been up 3535.84 s. Nothing in the log between boot and the oops
relates to swap or memory pressure.
=== WHAT WAS RULED OUT ===
- No OOM: no "Out of memory", no oom-killer records before either oops.
11 GB was free and swap usage was 0 at the time of crash #2.
- No thermal or throttling events, no MCE / EDAC errors in dmesg or kern.log.
(igen6_edac is loaded, it reported nothing.)
- Not a hardware reset: both events are kernel oopses followed by the kdump
capture kernel (boot -1, 14 s, cmdline elfcorehdr=...
systemd.unit=kdump-tools-dump.service)
and then a clean reboot.
- The other two reboots that day (20:39, 21:10) were user-initiated
shutdowns with full systemd shutdown/reboot.target logs — not crashes.
- The 22:05:41 point where journald stops is just its 5-minute flush
interval; the oops itself is at 22:09:05 (boot time 3535.84 s).
- Kernel is not tainted in crash #1; crash #2 only carries [I]
(FIRMWARE_WORKAROUND). No out-of-tree modules involved in the stacks.
=== WHY I THINK THIS IS THE SAME CLASS AS CVE-2026-64416 ===
1. Identical consumption path: zap_pte_range -> swap_pte_batch ->
lookup_swap_cgroup_id, reachable only when swap_pte_batch() accepts a
PTE that decodes as a swap entry without checking swap_info[].
(introduced by bea67dcc5eea "mm: attempt to batch free swap entries for
zap_pte_range()")
2. The other crash is the mirror image on the fork side: copy_nonpresent_pte
-> swap_dup_entry_direct -> __swap_duplicate, i.e. the same bad entry is
also consumed when a page table is duplicated. Fixing only the zap path
would leave this one open.
3. The register dumps show the same mask-looking constants in both crashes
(0x0003ffffffffbfff and 0x800000), suggesting the same bogus swp_entry
value is being handled. (Observation only, not proof.)
One difference from the upstream report: upstream says "on a swapless host
every ctrl->map is NULL", while this host does have /swap.img enabled — but
with 0 kB used. So if the 42.42 fix merely added the swap_info[] validation
on the zap path, this would not reproduce; if it was dropped or only partially
applied, it would. Worth checking whether swap_cgroup_ctrl[0].map is
populated on this host at all (swap_cgroup_swapon() is only reached under
certain memcg/swap-accounting conditions); if it is NULL here, that matches
the CVE's NULL-deref variant exactly.
=== OTHER OBSERVATIONS THAT MAY HELP ===
- Crash #1 and #2 happened under completely different workloads (image
loader vs. Chrome) but both at process teardown/duplication, i.e. the
failure needs a PTE that is already corrupt; it is not deterministic, it
fires whenever such a PTE is walked. That is also why "closing Chrome"
appears to be the trigger.
- /var/log/apport.log shows the second crash produced no report because of
"File exists: '/var/crash/linux-image-7.0.0-42-generic-202610291927.crash'".
The 22:09 vmcore (dump.202610292209, ~180 MB) is still on disk under
/var/crash/202610292209/ and was attached manually.
- Nothing of interest in code paths involving the i915/xe GPU drivers; both
stacks are pure core-mm.
- CVE-2026-64416 is listed as fixed in 7.0.0-31.31; there is no newer
linux-image-generic than 7.0.0-42.42 in resolute-updates at the time of
writing, so there is nothing to upgrade to.
=== REQUEST ===
- Please confirm whether the CVE-2026-64416 fix (upstream 63b02a9409cb) is
actually contained in 7.0.0-42.42, and whether the fork-side consumer
(swap_dup_entry_direct -> __swap_duplicate) needs the same validation.
- If you want the vmcore analysed: /var/crash/202610292209/dump.202610292209
(swapped out entry in the PTE could be recovered from it, which would
identify the exact type/offset and the VMA).
- Happy to run any tracing kernel or add debug patches you point me at.
=== ATTACHMENTS ===
dmesg-2209.txt full dmesg of the 22:09 crash (crash #2), copied from
/var/crash/202610292209/dmesg.202610292209
dmesg-1927.txt full dmesg of the 19:27 crash (crash #1), copied from
/var/crash/202610291927/dmesg.202610291927
linux-image-7.0.0-42-generic-202610291927.crash
apport report for crash #1 (40 KB, includes VmCoreDmesg)
NOT attached: /var/crash/202610292209/dump.202610292209, the 180 MB vmcore
for crash #2. It contains user memory so I would rather not upload it
publicly. It is preserved on disk -- please tell me where to send it (or
which parts to extract) and I will provide it.
The same dmesg excerpts are also quoted inline above in case attachment
access is inconvenient.
ProblemType: Bug
DistroRelease: Ubuntu 26.04
Package: linux-image-7.0.0-42-generic 7.0.0-42.42
ProcVersionSignature: Ubuntu 7.0.0-42.42-generic 7.0.14
Uname: Linux 7.0.0-42-generic x86_64
ApportVersion: 2.34.1-0ubuntu0.1
Architecture: amd64
AudioDevicesInUse:
USER PID ACCESS COMMAND
/dev/snd/controlC0: summer 3266 F.... pipewire
summer 3272 F.... wireplumber
/dev/snd/seq: summer 3266 F.... pipewire
CasperMD5CheckResult: fail
CurrentDesktop: ubuntu:GNOME
Date: Thu Oct 29 22:54:30 2026
InstallationDate: Installed on 2026-10-28 (1 days ago)
InstallationMedia: Ubuntu 26.04.1 LTS "Resolute Raccoon" - Release amd64
(20260826)
MachineType: LENOVO 20TA002CUS
ProcEnviron:
LANG=en_US.UTF-8
PATH=(custom, no user)
SHELL=/bin/bash
TERM=xterm-256color
ProcFB: 0 i915drmfb
ProcKernelCmdLine: BOOT_IMAGE=/vmlinuz-7.0.0-42-generic
root=UUID=114b815f-4928-4e2d-a686-d236f20bb6c3 ro quiet splash
crashkernel=2G-4G:320M,4G-32G:512M,32G-64G:1024M,64G-128G:2048M,128G-:4096M
SourcePackage: linux
UpgradeStatus: No upgrade log present (probably fresh install)
dmi.bios.date: 04/20/2026
dmi.bios.release: 1.67
dmi.bios.vendor: LENOVO
dmi.bios.version: R1EET67W(1.67 )
dmi.board.asset.tag: Not Available
dmi.board.name: 20TA002CUS
dmi.board.vendor: LENOVO
dmi.board.version: SDK0J40697 WIN
dmi.chassis.asset.tag: No Asset Information
dmi.chassis.type: 10
dmi.chassis.vendor: LENOVO
dmi.chassis.version: None
dmi.ec.firmware.release: 1.67
dmi.modalias:
dmi:bvnLENOVO:bvrR1EET67W(1.67):bd04/20/2026:br1.67:efr1.67:svnLENOVO:pn20TA002CUS:pvrThinkPadE14Gen2:rvnLENOVO:rn20TA002CUS:rvrSDK0J40697WIN:cvnLENOVO:ct10:cvrNone:skuLENOVO_MT_20TA_BU_Think_FM_ThinkPadE14Gen2:pfaThinkPadE14Gen2:
dmi.product.family: ThinkPad E14 Gen 2
dmi.product.name: 20TA002CUS
dmi.product.sku: LENOVO_MT_20TA_BU_Think_FM_ThinkPad E14 Gen 2
dmi.product.version: ThinkPad E14 Gen 2
dmi.sys.vendor: LENOVO
** Affects: linux (Ubuntu)
Importance: Undecided
Status: New
** Tags: amd64 apport-bug resolute
** Attachment added: "dmesg-2209.txt"
https://bugs.launchpad.net/bugs/2172503/+attachment/6013387/+files/dmesg-2209.txt
--
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2172503
Title:
Two kernel oopses in mm/swap PTE handling on 7.0.0-42-generic
(resolute-updates) — likely incomplete fix for CVE-2026-64416
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2172503/+subscriptions
--
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs