Relocate vDSO/vvar on restore so libc programs resume#140
Open
congwang-mk wants to merge 1 commit into
Open
Conversation
Signed-off-by: Cong Wang <cwang@multikernel.io>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The injection-based restore engine now relocates the kernel-provided
[vdso],[vvar], and[vvar_vclock]mappings onto the checkpoint-recorded bases (via injectedmremap) before the trampoline is torn down.Why
glibc/musl cache vDSO function pointers (e.g.
clock_gettime) at the vDSO's load-time base. A fresh restore stub maps its vDSO elsewhere under ASLR, so without relocation a restored libc program faulted on its first vDSO call. This was the gate on restoring ordinary programs: previously only vDSO-free (raw-syscall) binaries could be restored. Assumes a same-kernel restore (the vDSO code is byte-identical; only the ASLR base differs).Changes
checkpoint/resume.rs:plan_vdso_movescomputes a safe relocation order (no move clobbers a not-yet-moved source; an unresolvable swap is rejected rather than corrupting memory), driven through the existing injection trampoline. Pure ordering logic is unit-tested (5 cases).checkpoint/mod.rs:is_specialnow also recognizes[vvar_vclock](a newer-kernel split of[vvar]), so it is relocated rather than captured/restored as normal memory.restore_into/restore_interactiveupdated to reflect that vDSO now works.tests/rootfs-helper.c(new single-processclock-loopcommand callingclock_gettimeeach iteration). Checkpoints it mid-loop, kills the original, restores into a fresh sandbox, and asserts the restored process keeps advancing its counter (which requires every post-restore vDSO call to succeed).Deferred
The leftover-mapping sweep (unmapping the stub's residual mappings so the restored address space is exactly the checkpoint) is not included. Driving
munmaps through the ptrace single-step injection channel destabilizes that channel: once the stub's stack/TLS region is unmapped, subsequent injects SIGSEGV even with validrip/rsp/fs_baseand the gadget page intact. This needs a CRIU-style in-target restorer (a self-contained blob running inside the target with its own stack), tracked as follow-up. The/proc/self/mapsunion and supervisor-memory-exposure this would address already exist onmain, so nothing regresses.Testing
Full suite green: 486 lib tests, 290 integration tests, FFI restore tests, and the chroot tests that exercise the modified helper.