Skip to content

Contracts & Harnesses for non_null::sub and non_null::sub_ptr and non_null::offset_from #93

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 37 commits into from
Nov 27, 2024
Merged
Changes from 23 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
410afd2
added contract and proof for new_unchecked
Sep 12, 2024
83e7dea
add use safety
Sep 12, 2024
ceb381d
verification result
Sep 12, 2024
9f96cf5
make harness function name unique
QinyuanWu Sep 13, 2024
de1088c
add new_unchcked result and remove the old one
QinyuanWu Sep 14, 2024
5a4eaae
contract and harness for new
QinyuanWu Sep 18, 2024
5b94831
remove outdated kani log
QinyuanWu Sep 18, 2024
acf7687
complete the sub function proof
Jimmycreative Sep 24, 2024
456f83b
complete the sub ptr function and add random initial address for sub …
Jimmycreative Sep 26, 2024
ad15078
delete the log file for debugging
Jimmycreative Sep 26, 2024
bd5cd92
Merge branch 'model-checking:main' into jimmy_develop
Jimmycreative Sep 26, 2024
c25a12b
randomize the initial address for the pointer
Jimmycreative Sep 27, 2024
0a4ba99
Merge branch 'jimmy_develop' of github.com:danielhumanmod/verify-rust…
Jimmycreative Sep 27, 2024
17b4261
formatting & renaming for clarity
QinyuanWu Sep 27, 2024
6c00787
remove kani in contract to be tool agonistic
QinyuanWu Sep 27, 2024
b596967
working on the offset_from
Jimmycreative Oct 5, 2024
086c538
fix the merge coflict
Jimmycreative Oct 5, 2024
306dc73
fix the error
Jimmycreative Oct 5, 2024
31c3891
recover commented code
Jimmycreative Oct 5, 2024
11d6b2e
Remove .gitignore from version control
Jimmycreative Oct 5, 2024
201bb8e
Modify .gitignore to remove unnecessary line
Jimmycreative Oct 5, 2024
cbda879
keep gitignore consistent
Jimmycreative Oct 5, 2024
6e25173
fix some issue
Jimmycreative Oct 9, 2024
6a7bd8e
the SIZE should also be equal
Jimmycreative Oct 22, 2024
22ffb95
update
Jimmycreative Nov 13, 2024
6d4dbd4
fix the merge conflict
Jimmycreative Nov 13, 2024
d9b8199
use the same allocation to remove the assume in the contract
Jimmycreative Nov 13, 2024
d0a2480
modify the proof based on the suggestions
Jimmycreative Nov 13, 2024
023aca9
fix the proof based on the comments
Jimmycreative Nov 14, 2024
2697529
refine the code based on the suggestions
Jimmycreative Nov 22, 2024
ebfa640
refine the code based on the suggestions
Jimmycreative Nov 22, 2024
fc14b3b
remove the old comment
Jimmycreative Nov 22, 2024
1cfab67
fix the merge conflict
Jimmycreative Nov 26, 2024
2c5a795
Merge branch 'jimmy_develop' of github.com:danielhumanmod/verify-rust…
Jimmycreative Nov 26, 2024
557508e
refine the code based on the suggestions
Jimmycreative Nov 26, 2024
b820f74
fix the verification fail for sub_ptr
Jimmycreative Nov 26, 2024
1415903
fix the merge conflict
Jimmycreative Nov 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 78 additions & 1 deletion library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use crate::ub_checks::assert_unsafe_precondition;
use crate::{fmt, hash, intrinsics, ptr};
use safety::{ensures, requires};


#[cfg(kani)]
use crate::kani;

Expand Down Expand Up @@ -631,6 +630,9 @@ impl<T: ?Sized> NonNull<T> {
#[stable(feature = "non_null_convenience", since = "1.80.0")]
#[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")]
#[rustc_allow_const_fn_unstable(unchecked_neg)]
#[kani::requires(count.checked_mul(core::mem::size_of::<T>()).is_some())] // Prevent offset overflow
#[kani::requires(count * core::mem::size_of::<T>() <= isize::MAX as usize)]
#[kani::ensures(|result: &NonNull<T>| result.as_ptr() == self.as_ptr().offset(-(count as isize)))]
pub const unsafe fn sub(self, count: usize) -> Self
where
T: Sized,
Expand Down Expand Up @@ -762,6 +764,7 @@ impl<T: ?Sized> NonNull<T> {
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[stable(feature = "non_null_convenience", since = "1.80.0")]
#[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")]
#[kani::ensures(|result: &isize| *result == (self.as_ptr() as isize - origin.as_ptr() as isize) / core::mem::size_of::<T>() as isize)]
pub const unsafe fn offset_from(self, origin: NonNull<T>) -> isize
where
T: Sized,
Expand Down Expand Up @@ -855,6 +858,7 @@ impl<T: ?Sized> NonNull<T> {
#[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
#[unstable(feature = "ptr_sub_ptr", issue = "95892")]
#[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
#[kani::ensures(|result: &usize| *result == self.as_ptr().offset_from(subtracted.as_ptr()) as usize)]
pub const unsafe fn sub_ptr(self, subtracted: NonNull<T>) -> usize
where
T: Sized,
Expand Down Expand Up @@ -1803,4 +1807,77 @@ mod verify {
let maybe_null_ptr = if kani::any() { xptr as *mut i32 } else { null_mut() };
let _ = NonNull::new(maybe_null_ptr);
}

#[kani::proof_for_contract(NonNull::sub)]
pub fn non_null_check_sub() {
const SIZE: usize = 10;
// Randomiz pointer offset within array bound
let offset = kani::any_where(|x| *x < SIZE);
// Create a non-deterministic array of size SIZE
let arr: [i32; SIZE] = kani::any();
// Get a raw pointer to the array
let raw_ptr: *mut i32 = arr.as_ptr() as *mut i32;
// NonNUll pointer to the random offset
let ptr = unsafe { NonNull::new(raw_ptr.add(offset)).unwrap() };
// Create a non-deterministic count value
let count: usize = kani::any();

// SAFETY: Ensure that the subtraction does not go out of the bounds of the array
kani::assume(count < SIZE - offset);

unsafe {
// Perform the pointer subtraction from the last element
let result = ptr.sub(count);
}
}

#[kani::proof_for_contract(NonNull::sub_ptr)]
pub fn non_null_check_sub_ptr() {

const SIZE: usize = 100000;

let index = kani::any_where(|x| *x < SIZE);
// Create a non-deterministic array of size SIZE
let arr: [i32; SIZE] = kani::any();
// Get a raw pointer to the array
let raw_ptr: *mut i32 = arr.as_ptr() as *mut i32;

let ptr = unsafe { NonNull::new(raw_ptr.add(index)).unwrap() };
// Point to the first element of the array
let first_ptr = unsafe { NonNull::new(raw_ptr).unwrap() }; // Pointer to the first element

// Ensure that the memory is properly aligned
//kani::assume(raw_ptr as usize % mem::align_of::<i32>() == 0); // Ensure proper alignment


// Perform pointer subtraction safely
unsafe {
let distance = ptr.sub_ptr(first_ptr);
}
}

// todo: offset_from
#[kani::proof_for_contract(NonNull::offset_from)]
pub fn non_null_check_offset_from() {
const SIZE: usize = 200000;

let index = kani::any_where(|x| *x < SIZE);

let arr: [i32; SIZE] = kani::any(); // Create a non-deterministic array of size SIZE
let raw_ptr: *mut i32 = arr.as_ptr() as *mut i32; // Get a raw pointer to the array

let ptr = unsafe { NonNull::new(raw_ptr.add(index)).unwrap() }; // Pointer to random index

// Point to the first element of the array
let first_ptr = unsafe { NonNull::new(raw_ptr).unwrap() }; // Pointer to the first element

// Ensure that the memory is properly aligned
//kani::assume(raw_ptr as usize % mem::align_of::<i32>() == 0); // Ensure proper alignment

// Perform pointer subtraction safely
unsafe {
let distance = ptr.offset_from(first_ptr);
}
}

}