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 35 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
84 changes: 84 additions & 0 deletions library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -665,6 +665,12 @@ 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")]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))]
#[requires(
count.checked_mul(core::mem::size_of::<T>()).is_some() &&
count * core::mem::size_of::<T>() <= isize::MAX as usize &&
kani::mem::same_allocation(self.as_ptr(), self.as_ptr().wrapping_sub(count))
)]
#[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 @@ -794,6 +800,11 @@ 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")]
#[requires(
(kani::mem::same_allocation(self.as_ptr(), origin.as_ptr()) &&
((self.as_ptr().addr() - origin.as_ptr().addr()) % core::mem::size_of::<T>() == 0))
)] // Ensure both pointers meet safety conditions for offset_from
#[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 @@ -887,6 +898,10 @@ 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")]
#[requires(kani::mem::same_allocation(self.as_ptr(), subtracted.as_ptr()))] // Ensure both pointers are in the same allocation
#[requires((self.as_ptr().addr()) >= (subtracted.as_ptr().addr()))] // Ensure distance between pointers is non-negative
#[requires((self.as_ptr().addr() - subtracted.as_ptr().addr()) % core::mem::size_of::<T>() == 0)]
#[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 @@ -2386,4 +2401,73 @@ mod verify {
// Perform the alignment check
let result = non_null_ptr.is_aligned_to(align);
}

#[kani::proof_for_contract(NonNull::sub)]
pub fn non_null_check_sub() {
const SIZE: usize = 10000;
let mut generator = kani::PointerGenerator::<SIZE>::new();
// Get a raw pointer from the generator within bounds
let raw_ptr: *mut i32 = generator.any_in_bounds().ptr;
// Create a non-null pointer from the raw pointer
let ptr = unsafe { NonNull::new(raw_ptr).unwrap() };
// Create a non-deterministic count value
let count: usize = kani::any();

unsafe {
let result = ptr.sub(count);
}
}

#[kani::proof_for_contract(NonNull::sub_ptr)]
pub fn non_null_check_sub_ptr() {
const SIZE: usize = core::mem::size_of::<i32>() * 1000;
let mut generator1 = kani::PointerGenerator::<SIZE>::new();
let mut generator2 = kani::PointerGenerator::<SIZE>::new();

let ptr: *mut i32 = if kani::any() {
generator1.any_in_bounds().ptr as *mut i32
} else {
generator2.any_in_bounds().ptr as *mut i32
};

let origin: *mut i32 = if kani::any() {
generator1.any_in_bounds().ptr as *mut i32
} else {
generator2.any_in_bounds().ptr as *mut i32
};

let ptr_nonnull = unsafe { NonNull::new(ptr).unwrap() };
let origin_nonnull = unsafe { NonNull::new(origin).unwrap() };

unsafe {
let distance = ptr_nonnull.sub_ptr(origin_nonnull);
}
}

#[kani::proof_for_contract(NonNull::offset_from)]
#[kani::should_panic]
pub fn non_null_check_offset_from() {
const SIZE: usize = core::mem::size_of::<i32>() * 1000;
let mut generator1 = kani::PointerGenerator::<SIZE>::new();
let mut generator2 = kani::PointerGenerator::<SIZE>::new();

let ptr: *mut i32 = if kani::any() {
generator1.any_in_bounds().ptr as *mut i32
} else {
generator2.any_in_bounds().ptr as *mut i32
};

let origin: *mut i32 = if kani::any() {
generator1.any_in_bounds().ptr as *mut i32
} else {
generator2.any_in_bounds().ptr as *mut i32
};

let ptr_nonnull = unsafe { NonNull::new(ptr).unwrap() };
let origin_nonnull = unsafe { NonNull::new(origin).unwrap() };

unsafe {
let distance = ptr_nonnull.offset_from(origin_nonnull);
}
}
}
Loading