Skip to content

checkpoint: execve-stub restore path (primitive proof)#141

Merged
congwang-mk merged 10 commits into
mainfrom
feat/execve-stub-restore
Jul 14, 2026
Merged

checkpoint: execve-stub restore path (primitive proof)#141
congwang-mk merged 10 commits into
mainfrom
feat/execve-stub-restore

Conversation

@congwang-mk

Copy link
Copy Markdown
Contributor

Summary

Introduces the execve-stub restore path: a checkpoint is restored by exec-ing a freestanding stub into a fresh process that self-reconstructs its address space, rather than driving a puppet through ptrace injection. This first cut proves the primitive end to end for a trivial single-region program, entirely unprivileged (no sysctl, no CAP_SYS_PTRACE).

How it works

  1. The supervisor serializes the checkpoint into a compact control blob (region table, GP register file, anonymous page bytes) on a memfd.
  2. It exec's restore-stub (a freestanding, no-libc, no-PIE binary) with the blob and two eventfds on fixed inherited fds.
  3. The stub maps each anonymous region MAP_FIXED with its captured prot, registers them with userfaultfd (missing mode), exposes the uffd to the supervisor, signals READY, waits for GO, then rt_sigreturns into the checkpoint register context.
  4. The supervisor acquires the stub's uffd via pidfd_getfd and serves each faulting page with UFFDIO_COPY from the blob.

What is proven

The end-to-end test restores a hand-assembled program (write a sentinel byte to an inherited pipe, then exit) whose code lives in an anonymous region served on fault. Reading the sentinel proves the stub mapped the region, registered uffd, rt_sigreturnd to the checkpoint rip/rsp, and the pager filled the faulting code page.

Notable correctness points

  • The userfaultfd is created O_NONBLOCK: poll() on a blocking uffd always reports POLLERR, so a polling pager would never see a fault.
  • On hosts with vm.unprivileged_userfaultfd=0, creation falls back to UFFD_USER_MODE_ONLY, which serves the user-mode faults this path relies on without privilege.
  • Region prot is honored (an executable region mapped without PROT_EXEC would fault as a protection violation rather than a serviceable missing-page fault).

Known limitations (follow-up)

  • The stub is -no-pie and links low; restoring a real program whose own text occupies that range would clobber the running stub. The next phase relocates the stub out of the way.
  • Only anonymous regions are handled: no file-backed regions, no in-stub vDSO relocation, no FP/xstate, no fd-table reopen yet.
  • USER_MODE_ONLY cannot serve kernel-mode faults (a syscall touching an unfilled page); the planned solution is prefaulting pointer args from the seccomp-notify supervisor.

Testing

  • checkpoint unit tests (blob round-trip, pager page service): pass.
  • New test_restore_stub end-to-end integration test: pass.
  • Existing injection-based restore test: pass (no regression).

🤖 Generated with Claude Code

Signed-off-by: Cong Wang <cwang@multikernel.io>
Signed-off-by: Cong Wang <cwang@multikernel.io>
Signed-off-by: Cong Wang <cwang@multikernel.io>
Signed-off-by: Cong Wang <cwang@multikernel.io>
Signed-off-by: Cong Wang <cwang@multikernel.io>
…_DIR

Signed-off-by: Cong Wang <cwang@multikernel.io>
Signed-off-by: Cong Wang <cwang@multikernel.io>
Signed-off-by: Cong Wang <cwang@multikernel.io>
…h) and mark staged code

Signed-off-by: Cong Wang <cwang@multikernel.io>
… build warnings

Signed-off-by: Cong Wang <cwang@multikernel.io>
@congwang-mk congwang-mk force-pushed the feat/execve-stub-restore branch from d136f85 to b50df02 Compare July 13, 2026 22:02
@congwang-mk congwang-mk merged commit c63cf0e into main Jul 14, 2026
13 checks passed
@congwang-mk congwang-mk deleted the feat/execve-stub-restore branch July 14, 2026 23:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant