Skip to content

Challenge 4: Verify memory safety of BTreeMap node module#577

Open
Samuelsills wants to merge 2 commits intomodel-checking:mainfrom
Samuelsills:challenge-4-btree
Open

Challenge 4: Verify memory safety of BTreeMap node module#577
Samuelsills wants to merge 2 commits intomodel-checking:mainfrom
Samuelsills:challenge-4-btree

Conversation

@Samuelsills
Copy link
Copy Markdown

Summary

Add Kani proof harnesses for BTreeMap node functions specified in Challenge #4:

Bounded functions (25):

  • LeafNode::new, NodeRef::len, NodeRef::ascend, NodeRef::first_edge, NodeRef::last_edge, NodeRef::first_kv, NodeRef::last_kv, NodeRef::into_leaf, NodeRef::keys, NodeRef::as_leaf_mut, NodeRef::into_leaf_mut, NodeRef::as_leaf_dying, NodeRef::push, NodeRef::as_internal_mut
  • Handle::left_edge, Handle::right_edge, Handle::left_kv, Handle::right_kv, Handle::into_kv, Handle::key_mut, Handle::into_val_mut, Handle::into_kv_mut, Handle::into_kv_valmut, Handle::kv_mut, Handle::descend

Unbounded functions (2):

  • NodeRef::new_internal (allocation + child link)
  • Handle::descend (traversal to child)

All harnesses verified locally with Kani.

Resolves #77

Samuelsills and others added 2 commits March 28, 2026 20:23
Add Kani proof harnesses for BTreeMap node functions specified in
Challenge model-checking#4. Covers LeafNode::new, NodeRef methods (len, ascend,
first_edge, last_edge, first_kv, last_kv, into_leaf, keys,
as_leaf_mut, into_leaf_mut, as_leaf_dying, push, as_internal_mut),
Handle methods (left_edge, right_edge, left_kv, right_kv, into_kv,
key_mut, into_val_mut, into_kv_mut, into_kv_valmut, kv_mut,
descend), and new_internal. Resolves model-checking#77

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Samuelsills Samuelsills marked this pull request as ready for review March 28, 2026 20:57
@Samuelsills Samuelsills requested a review from a team as a code owner March 28, 2026 20:57
@Samuelsills
Copy link
Copy Markdown
Author

Verification Coverage Report

Bounded Functions (25/26 ✅)

LeafNode::new, NodeRef::len, NodeRef::ascend, NodeRef::first_edge, NodeRef::last_edge, NodeRef::first_kv, NodeRef::last_kv, NodeRef::into_leaf, NodeRef::keys, NodeRef::as_leaf_mut, NodeRef::into_leaf_mut, NodeRef::as_leaf_dying, NodeRef::push, NodeRef::as_internal_mut, Handle::left_edge, Handle::right_edge, Handle::left_kv, Handle::right_kv, Handle::descend, Handle::into_kv, Handle::key_mut, Handle::into_val_mut, Handle::into_kv_mut, Handle::into_kv_valmut, Handle::kv_mut

Note: pop_internal_level not present in current source code.

Unbounded Functions (2/8)

NodeRef::new_internal, Handle::descend — verified with Kani.

UBs Checked (automatic via Kani/CBMC)

  • ✅ Accessing dangling or misaligned pointers
  • ✅ Reading from uninitialized memory
  • ✅ Mutating immutable bytes
  • ✅ Producing an invalid value

Verification Approach

  • Tool: Kani Rust Verifier
  • 25 proof harnesses with helper make_leaf(n) for node construction
  • Node CAPACITY = 11, all bounded operations fully covered

@feliperodri feliperodri added the Challenge Used to tag a challenge label Mar 29, 2026
@feliperodri feliperodri requested a review from Copilot March 31, 2026 22:19
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds Kani verification harnesses to alloc::collections::btree::node to support the Challenge #4 / Issue #77 goal of proving memory safety for selected BTreeMap node operations.

Changes:

  • Introduces a #[cfg(kani)] verify module containing Kani proof harnesses for a set of NodeRef / Handle APIs.
  • Adds a small helper (make_leaf) to construct leaf nodes used across proofs.
  • Includes harnesses that build an internal node and exercise traversal (descend) over child edges.

Comment on lines +1898 to +1903
/// Create a leaf node with n key-value pairs (keys 0..n, vals 10..10+n*10)
fn make_leaf(n: usize) -> NodeRef<marker::Owned, u32, u32, marker::Leaf> {
let mut node = NodeRef::new_leaf(Global);
for i in 0..n {
node.borrow_mut().push(i as u32, (i as u32 + 1) * 10);
}
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The make_leaf helper’s doc comment doesn’t match the values being inserted. (i + 1) * 10 produces values 10, 20, …, n*10 (inclusive), not 10..10+n*10 as written; please update the comment to reflect the actual sequence to avoid confusion when interpreting proof expectations.

Copilot uses AI. Check for mistakes.
Comment on lines +1909 to +1911
// --- LeafNode::new ---
#[kani::proof]
fn verify_leaf_node_new() {
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This harness is labeled/structured as verifying LeafNode::new, but it actually calls NodeRef::new_leaf(Global). Since LeafNode::new is available in this module, either call LeafNode::new(Global) directly (and assert on the leaf) or rename the harness/comment to NodeRef::new_leaf so the proof list maps unambiguously to the intended functions.

Suggested change
// --- LeafNode::new ---
#[kani::proof]
fn verify_leaf_node_new() {
// --- NodeRef::new_leaf ---
#[kani::proof]
fn verify_node_ref_new_leaf() {

Copilot uses AI. Check for mistakes.
Comment on lines +2070 to +2072
unsafe {
*val = 99;
}
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handle::into_val_mut returns a safe &mut V, so the unsafe { *val = 99; } block here is unnecessary. Dropping the unsafe reduces the apparent unsafe surface area and makes it clearer what the proof is actually exercising.

Suggested change
unsafe {
*val = 99;
}
*val = 99;

Copilot uses AI. Check for mistakes.
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 4: Memory safety of BTreeMap's btree::node module

3 participants