[BUG] liveupdate/memfd: duplicate memfd preserve restores same KHO folio twice

From: Yifei Chu

Date: Sun May 24 2026 - 10:45:02 EST


Hello,

Short version: I found that the same memfd can be preserved more than once in a single liveupdate session under different tokens. After kexec, those tokens can both refer to the same preserved KHO folio, and the second restore path hits kho_restore_page(). With panic_on_warn=1, this is a reproducible panic.

The core issue seems to be that mm/memfd_luo.c records the same underlying folio PFNs for each preserved token, while KHO page preservation is one-shot state rather than reference-counted ownership.

I reproduced two variants.

Variant A: duplicate preserve, retrieve both tokens

  1. Create one liveupdate session.
  2. Create one 4 KiB memfd and write a marker.
  3. Call LIVEUPDATE_SESSION_PRESERVE_FD twice for the same memfd with two distinct tokens.
  4. Keep the session fd alive across kexec.
  5. In the second kernel, retrieve token A successfully.
  6. Retrieve token B, which attempts to restore the same KHO folio again.

Observed result:

[stage2] token A marker=’duplicate-preserve-marker’
[stage2] retrieving token B should hit duplicate KHO folio restore
WARNING: kernel/liveupdate/kexec_handover.c:256 at kho_restore_page+0x11e/0x280
memfd_luo_retrieve+0x1aa/0x490
luo_session_retrieve_fd+0x73/0x130
Kernel panic - not syncing: kernel: panic_on_warn set …

Variant B: duplicate preserve, FINISH an unretrieved session

  1. Preserve the same memfd twice under different tokens.
  2. Kexec into the second kernel.
  3. Retrieve the session but do not retrieve individual fds.
  4. Call LIVEUPDATE_SESSION_FINISH.

Observed result:

[stage2] finishing session should hit duplicate KHO restore
WARNING: kernel/liveupdate/kexec_handover.c:256 at kho_restore_page+0x11e/0x280
memfd_luo_finish+0x10f/0x190
luo_session_finish+0x31/0xa0
Kernel panic - not syncing: kernel: panic_on_warn set …

Tested environment:

Linux version 7.0.9, x86_64 QEMU
gcc 12.3.0, GNU ld 2.38
CONFIG_LIVEUPDATE=y
CONFIG_LIVEUPDATE_MEMFD=y
CONFIG_KEXEC_HANDOVER=y
CONFIG_KASAN=y in the tested config
Boot args included: kho=on liveupdate=on panic_on_warn=1

My read is that duplicate preservation of the same underlying memfd/inode should either be rejected within a session, or KHO preserved-page ownership would need reference-counted semantics so duplicate logical owners cannot independently consume the same physical folio.

The attached tarball has both PoC directories, full QEMU serial logs, kernel configs, and README files.

I reproduced the panics on the 7.0.9 QEMU build above. I also checked current mainline mm/memfd_luo.c for an obvious duplicate-preserve guard, but I have not yet runtime-tested current mainline.

Thanks,
Chuyifei

Attachment: liveupdate_duplicate_memfd_warn_panic.tar.gz
Description: Unix tar archive