Skip to content

Commit 5f2125c

Browse files
committed
Refactors the contracts and add harnesses to test invalid count / casting to unit type
1 parent 534ce59 commit 5f2125c

File tree

2 files changed

+55
-17
lines changed

2 files changed

+55
-17
lines changed

library/core/src/ptr/const_ptr.rs

+25-6
Original file line numberDiff line numberDiff line change
@@ -470,8 +470,7 @@ impl<T: ?Sized> *const T {
470470
// Else if count is not zero, then ensure that adding `count` doesn't cause
471471
// overflow and that both pointers `self` and the result are in the same
472472
// allocation
473-
(mem::size_of_val_raw(self) != 0 &&
474-
(self.addr() as isize).checked_add(count).is_some() &&
473+
((self.addr() as isize).checked_add(count).is_some() &&
475474
kani::mem::same_allocation(self, self.wrapping_byte_offset(count)))
476475
)]
477476
#[ensures(|&result|
@@ -1008,8 +1007,7 @@ impl<T: ?Sized> *const T {
10081007
// Else if count is not zero, then ensure that adding `count` doesn't cause
10091008
// overflow and that both pointers `self` and the result are in the same
10101009
// allocation
1011-
(mem::size_of_val_raw(self) != 0 &&
1012-
(self.addr() as isize).checked_add(count as isize).is_some() &&
1010+
((self.addr() as isize).checked_add(count as isize).is_some() &&
10131011
kani::mem::same_allocation(self, self.wrapping_byte_add(count)))
10141012
)]
10151013
#[ensures(|&result|
@@ -1138,8 +1136,7 @@ impl<T: ?Sized> *const T {
11381136
// Else if count is not zero, then ensure that subtracting `count` doesn't
11391137
// cause overflow and that both pointers `self` and the result are in the
11401138
// same allocation
1141-
(mem::size_of_val_raw(self) != 0 &&
1142-
(self.addr() as isize).checked_sub(count as isize).is_some() &&
1139+
((self.addr() as isize).checked_sub(count as isize).is_some() &&
11431140
kani::mem::same_allocation(self, self.wrapping_byte_sub(count)))
11441141
)]
11451142
#[ensures(|&result|
@@ -2105,6 +2102,28 @@ mod verify {
21052102
check_const_offset_from_tuple_4_arr
21062103
);
21072104

2105+
#[kani::proof_for_contract(<*const ()>::byte_offset)]
2106+
#[kani::should_panic]
2107+
pub fn check_const_byte_offset_unit_invalid_count() {
2108+
let val = ();
2109+
let ptr: *const () = &val;
2110+
let count: isize = kani::any_where(|&x| x != (mem::size_of::<()>() as isize));
2111+
unsafe {
2112+
ptr.byte_offset(count);
2113+
}
2114+
}
2115+
2116+
#[kani::proof_for_contract(<*const ()>::byte_offset)]
2117+
pub fn check_const_byte_offset_cast_unit() {
2118+
let mut generator = PointerGenerator::<ARRAY_LEN>::new();
2119+
let ptr: *const u8 = generator.any_in_bounds().ptr;
2120+
let ptr1: *const () = ptr as *const ();
2121+
let count: isize = kani::any();
2122+
unsafe {
2123+
ptr1.byte_offset(count);
2124+
}
2125+
}
2126+
21082127
// generate proof for contracts of byte_add, byte_sub and byte_offset to verify
21092128
// unit pointee type
21102129
// - `$fn_name`: function for which the contract must be verified

library/core/src/ptr/mut_ptr.rs

+30-11
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,7 @@ impl<T: ?Sized> *mut T {
484484
// Else if count is not zero, then ensure that subtracting `count` doesn't
485485
// cause overflow and that both pointers `self` and the result are in the
486486
// same allocation
487-
(mem::size_of_val_raw(self) != 0 &&
488-
(self.addr() as isize).checked_add(count).is_some() &&
487+
((self.addr() as isize).checked_add(count).is_some() &&
489488
kani::mem::same_allocation(self, self.wrapping_byte_offset(count)))
490489
)]
491490
#[ensures(|&result|
@@ -1111,8 +1110,7 @@ impl<T: ?Sized> *mut T {
11111110
// Else if count is not zero, then ensure that subtracting `count` doesn't
11121111
// cause overflow and that both pointers `self` and the result are in the
11131112
// same allocation
1114-
(mem::size_of_val_raw(self) != 0 &&
1115-
(self.addr() as isize).checked_add(count as isize).is_some() &&
1113+
((self.addr() as isize).checked_add(count as isize).is_some() &&
11161114
kani::mem::same_allocation(self, self.wrapping_byte_add(count)))
11171115
)]
11181116
#[ensures(|&result|
@@ -1258,8 +1256,7 @@ impl<T: ?Sized> *mut T {
12581256
// Else if count is not zero, then ensure that subtracting `count` doesn't
12591257
// cause overflow and that both pointers `self` and the result are in the
12601258
// same allocation
1261-
(mem::size_of_val_raw(self) != 0 &&
1262-
(self.addr() as isize).checked_sub(count as isize).is_some() &&
1259+
((self.addr() as isize).checked_sub(count as isize).is_some() &&
12631260
kani::mem::same_allocation(self, self.wrapping_byte_sub(count)))
12641261
)]
12651262
#[ensures(|&result|
@@ -2410,6 +2407,31 @@ mod verify {
24102407
use core::mem;
24112408
use kani::PointerGenerator;
24122409

2410+
// bounding space for PointerGenerator to accommodate 40 elements.
2411+
const ARRAY_LEN: usize = 40;
2412+
2413+
#[kani::proof_for_contract(<*mut ()>::byte_offset)]
2414+
#[kani::should_panic]
2415+
pub fn check_mut_byte_offset_unit_invalid_count() {
2416+
let mut val = ();
2417+
let ptr: *mut () = &mut val;
2418+
let count: isize = kani::any_where(|&x| x > (mem::size_of::<()>() as isize));
2419+
unsafe {
2420+
ptr.byte_offset(count);
2421+
}
2422+
}
2423+
2424+
#[kani::proof_for_contract(<*mut ()>::byte_offset)]
2425+
pub fn check_mut_byte_offset_cast_unit() {
2426+
let mut generator = PointerGenerator::<ARRAY_LEN>::new();
2427+
let ptr: *mut u8 = generator.any_in_bounds().ptr;
2428+
let ptr1: *mut () = ptr as *mut ();
2429+
let count: isize = kani::any();
2430+
unsafe {
2431+
ptr1.byte_offset(count);
2432+
}
2433+
}
2434+
24132435
// generate proof for contracts of byte_add, byte_sub and byte_offset to verify
24142436
// unit pointee type
24152437
// - `$fn_name`: function for which the contract must be verified
@@ -2420,7 +2442,7 @@ mod verify {
24202442
pub fn $proof_name() {
24212443
let mut val = ();
24222444
let ptr: *mut () = &mut val;
2423-
let count: isize = kani::any();
2445+
let count: isize = mem::size_of::<()>() as isize;
24242446
unsafe {
24252447
ptr.byte_offset(count);
24262448
}
@@ -2433,7 +2455,7 @@ mod verify {
24332455
let mut val = ();
24342456
let ptr: *mut () = &mut val;
24352457
//byte_add and byte_sub need count to be usize unlike byte_offset
2436-
let count: usize = kani::any();
2458+
let count: usize = mem::size_of::<()>();
24372459
unsafe {
24382460
ptr.$fn_name(count);
24392461
}
@@ -2445,9 +2467,6 @@ mod verify {
24452467
gen_mut_byte_arith_harness_for_unit!(byte_sub, check_mut_byte_sub_unit);
24462468
gen_mut_byte_arith_harness_for_unit!(byte_offset, check_mut_byte_offset_unit);
24472469

2448-
// bounding space for PointerGenerator to accommodate 40 elements.
2449-
const ARRAY_LEN: usize = 40;
2450-
24512470
// generate proof for contracts for byte_add, byte_sub and byte_offset
24522471
// - `$type`: pointee type
24532472
// - `$fn_name`: function for which the contract must be verified

0 commit comments

Comments
 (0)