Skip to content

Challenge 29: Kani contracts for Box, convert, and ThinBox - #639

Open
sankalpsthakur wants to merge 5 commits into
model-checking:mainfrom
sankalpsthakur:challenge/29-boxed
Open

Challenge 29: Kani contracts for Box, convert, and ThinBox#639
sankalpsthakur wants to merge 5 commits into
model-checking:mainfrom
sankalpsthakur:challenge/29-boxed

Conversation

@sankalpsthakur

@sankalpsthakur sankalpsthakur commented Aug 20, 2026

Copy link
Copy Markdown

Summary

Kani safety contracts and proof harnesses for Challenge 29 (Box / convert / ThinBox). Runtime stdlib logic is unchanged; annotations are cfg(kani) plus the repo-standard tool-agnostic safety::{requires, ensures} attributes (not cfg_attr(kani, kani::requires)).

In-window ticket (end 2026-12-31, $15,000 USD). Tracking #526.

Success criteria mapping

Required unsafe functions (contracts + verified harnesses):

  • Box<MaybeUninit<T>, A>::assume_init and slice form — #[requires]/#[ensures] + proof_for_contract
  • Box::from_raw, from_non_null, from_raw_in, from_non_null_in — same, including sized + slice instantiations. Reconstructors require a layout predicate: ub_checks::can_dereference and Layout::for_value_raw size <= isize::MAX (allocator provenance is a caller obligation we cannot express). Slice from_raw_in / from_non_null_in harnesses allocate without Box::from so proof_for_contract sees a single top-level call.
  • Unchecked downcast: the challenge table lists <dyn Error>::downcast_unchecked (×3). That API does not exist in this tree (impl dyn Error only has safe downcast). The three real methods are Box<dyn Any (+ Send) (+ Sync), A>::downcast_unchecked. Those three carry safety contracts; harnesses execute the bodies under is::<T>(). Kani cannot proof_for_contract the trait-object generic methods (resolver lists the three impls and rejects angle-bracket paths).

Safe wrappers (≥75% of 46): 45/46 covered (the listed TryFrom<Box<T>> impl does not exist; TryFrom<Vec<T>> is extra). Includes ThinBox Deref/DerefMut/Drop/meta/with_header and WithHeader::{new, try_new, new_unsize_zst, header}, from_slice (TrivialClone + Clone), Error/Any downcast ok/err paths, into_pin with !Unpin. Slice constructors and reconstructors use bounded symbolic lengths (kani::any_where / any_slice_of_array), not only fixed 0/1.

UBs: dangling/misaligned access, intrinsic UB, mutating immutable bytes, invalid values — via Kani's default checks on the real std bodies. No cfg(not(kani)) body swap.

Validation

  • Worktree challenge/29-boxed, head 4da62f00d5c02a9d1ba4457da136be459a539212
  • Authoritative launch is GitHub Actions scripts/run-kani.sh
  • Kani run 32560286046: partitions 1–4 SUCCESS on ubuntu and macos. Autoharness ubuntu Complete - 1447 successfully verified harnesses, 0 failures. Autoharness macos Complete - 1446 successfully verified harnesses, 0 failures. Kani List, Metrics, Autoharness Analyzer, Build JSON SUCCESS.
  • Flux, GOTO, VeriFast, KMIR, upstream_test ubuntu+macos, simd, build: SUCCESS

Fixes #526

AI/LLM disclosure

  • AI coding tools (including Grok and/or Codex agent-assisted editing) were used to help draft or modify code and this PR description.
  • I reviewed the complete change, understand the reasoning, and take responsibility for the contracts and harnesses.
  • This submission is original work of authorship under the project contributor terms; AI output was not pasted unreviewed.

Kani contracts and harnesses for verify-rust-std challenge.

Fixes rust-lang#526
@sankalpsthakur
sankalpsthakur requested a review from a team as a code owner August 20, 2026 12:08
Place #[cfg(kani)] use core::kani with neighboring core uses and group
use core::{fmt, kani} so the upstream_test format check passes.
Autoharness macos/ubuntu failed on check_downcast_any,
check_downcast_error, and check_from_slice_clone (CBMC timeout).
Match the passing sibling proofs: is_ok/is_err only, fixed-length
Clone from_slice with unwind(3). No runtime stdlib change.

Fixes rust-lang#526
@sankalpsthakur

Copy link
Copy Markdown
Author

Ready for committee FCFS review of Challenge 29 (in-window, end 2026-12-31).

Head 5d8f0ee99218643bc7eb62fe39aa70b6c43508cb:

  • Kani partitions 1–4 SUCCESS
  • Autoharness ubuntu: 1445 harnesses, 0 failures
  • Autoharness macos: 1444 harnesses, 0 failures
  • Flux, GOTO, VeriFast, upstream_test SUCCESS
  • Contracts use repo-standard safety::{requires, ensures}

Tracking Fixes #526. No second solution PR.

@feliperodri feliperodri added the Challenge Used to tag a challenge label Aug 20, 2026
Documented Box reconstruction requires more than non-null dereference:
size must fit isize::MAX. Encode that with a kani-only layout check on
from_raw / from_non_null / from_raw_in / from_non_null_in.

Use symbolic slice lengths (capped at 2) on reconstructors and slice
constructors, and add from_raw_in / from_non_null_in slice harnesses.
proof_for_contract allows one top-level from_raw_in call.
Box::from already goes through from_raw_in, so macos partition 2
failed check_from_raw_in_slice. Mirror alloc_write for [u8].
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Challenge Used to tag a challenge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Challenge 29: Safety of boxed

2 participants