Challenge 2: Verify safety of raw-pointer intrinsics with Kani - #668
Challenge 2: Verify safety of raw-pointer intrinsics with Kani#668v3risec wants to merge 2 commits into
Conversation
|
Thanks @v3risec — this is a solid, sound submission. It's clean on our vacuity checks (no cfg(kani) body swaps, no decorative contracts — every contracted fn has a matching Where it fell short of closing Challenge 2 — it's incomplete relative to the criteria:
For transparency: we reviewed all three open Challenge 2 solutions together and are prioritizing #649 in the review process, which covers all 21 intrinsics + 5/5 usages + 5/5 wrappers. Your bug fix and the fallback-sharing pattern are genuinely valuable — worth surfacing to that PR/upstream regardless. One thing to watch: adding |
Summary
This PR adds a Kani-based verification plan for Challenge 2.
The changes are organized into four layers:
typed_swap_nonoverlappingfallback;The
typed_swap_nonoverlappingfallback is extracted into a shared helper so the production path and the verification wrapper execute the same fallback body.Current Source Mapping
Some names and locations in the challenge table do not match the current source tree:
<[T]>::copy_from_sliceis a safe method inlibrary/core/src/slice/mod.rs; there is no separatestd::ptr::copy_from_sliceimplementation.mem::align_of_valis the current implementation. The deprecatedmin_align_of_valfunction forwards to it.mem::zeroed<T>is implemented inlibrary/core/src/mem/mod.rs.MaybeUninit::zeroedis a separate safe constructor inlibrary/core/src/mem/maybe_uninit.rs.parse_u64_intois not present in the current source tree, so no proof is claimed for it.typed_swap_nonoverlapping; the challenge table refers to the corresponding typed swap operation astyped_swap.Part 1: Intrinsic Coverage
typed_swap_nonoverlappingvtable_sizevtable_aligncopy_nonoverlappingcopywrite_bytessize_of_valdyn Debugwrapper harnesses using checked raw-layout predicatesarith_offsetvolatile_loadvolatile_storecompare_bytesptr_offset_fromptr_offset_from_unsignedread_via_copywrite_via_movevolatile_copy_memory,volatile_copy_nonoverlapping_memory,volatile_set_memory,unaligned_volatile_load, andunaligned_volatile_storeBecause Kani cannot currently attach contracts directly to several body-less intrinsic declarations (Kani rust-lang#3325), the copy, layout, arithmetic, volatile, comparison, read, and write proofs use ordinary wrapper functions. These wrappers provide verification evidence but should not be described as declaration-level production contracts.
Pending volatile intrinsic coverage
The following five intrinsic targets are not covered by this change:
volatile_copy_nonoverlapping_memoryvolatile_copy_memoryvolatile_set_memoryunaligned_volatile_loadunaligned_volatile_storeThis is a limitation of the Kani version currently pinned by
verify-rust-std, rather than a remaining limitation of upstream Kani. The repository pins Kani commitd4df833c8f8f18e632e7b0a7945bb2161f708990from January 18, 2026.Upstream support for these intrinsics has since been implemented and merged:
volatile_copy_memory,volatile_copy_nonoverlapping_memory, andvolatile_set_memory.unaligned_volatile_loadandunaligned_volatile_store.Once
verify-rust-stdupdates its pinned Kani revision to include these changes, contracts and proof harnesses for the five remaining targets can be added and verified using the same approach as the intrinsics covered here.Part 2: Standard-Library Usage
<[T]>::copy_from_slicemem::swapmem::align_of_valalign_of::<T>()MaybeUninit::zeroedTparse_u64_intoPart 3: Public APIs Exposing Intrinsics
ptr::swapptr::write_bytesmem::align_of_val_rawdyn Debugharnessesmem::zeroedModel Correspondence
copyandcopy_nonoverlappingare modeled at byte level. The oracle checks preservation of initialization state, including the corresponding source and destination element offsets. It is not a universal byte-value oracle for arbitraryT.write_bytesis modeled as a writable byte-range operation. The current harnesses check contract reachability and memory conditions, but do not independently assert the resulting fill byte.vtable_size,vtable_align,size_of_val, andalign_of_val_rawuse compiler-generated metadata and Kani's checked raw-layout predicates. This establishes consistency for the instantiated types, not a complete proof of every rustc layout.arith_offsetis checked against wrapping pointer arithmetic postconditions.volatile_loadandvolatile_storecurrently model ordinary Rust-allocation-backed memory only.compare_bytes,read_via_copy,write_via_move, and the volatile wrappers currently establish memory-safety conditions, not complete independent value semantics.Harness Audit
isize/usize, floating-point values,bool,char, arrays,NonZeroI32, and unit.align_of_val_rawcovers the full sized scalar matrix,u8throughu128slices, and representativedyn Debugvalues.ptr::write_bytes::<()>harness uses a real byte allocation because Kani cannot represent a writable zero-sized memset destination. This is a harness-only workaround and does not change production code.Verification
All added Challenge 2 harnesses pass locally with Kani.
Resolves #16
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.