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

Reply via email to