Skip to content

Commit fa0d1ec

Browse files
committed
A few tests adjustments including a new fixme test
1 parent 1dbaed7 commit fa0d1ec

File tree

4 files changed

+49
-30
lines changed

4 files changed

+49
-30
lines changed
Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,12 @@
1-
FAILURE\
2-
assertion failed: high_offset == wrapped_offset.try_into().unwrap()
1+
Checking harness check_wrap_around_ptr...
2+
VERIFICATION:- SUCCESSFUL
3+
4+
Checking harness harness_without_ub...
5+
VERIFICATION:- SUCCESSFUL
6+
7+
Checking harness original_harness...
8+
Failed Checks: assertion failed: high_offset == wrapped_offset.try_into().unwrap()
9+
VERIFICATION:- FAILED
10+
11+
Verification failed for - original_harness
12+
Complete - 2 successfully verified harnesses, 1 failures, 3 total.

tests/expected/offset-wraps-around/main.rs

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
//! the add operation wraps.
66
//!
77
//! Note that CBMC offset logic will wrap around the object bits, not the entire address space, when
8-
//! computing the offset between pointers. Doing that is UB in Rust, so we should be OK
9-
//! as long as Kani can detect UB in that case.
8+
//! computing the offset between pointers.
9+
//! See <https://github.com/model-checking/kani/issues/1150> for more details.
1010
1111
use std::convert::TryInto;
1212

@@ -15,15 +15,14 @@ fn original_harness() {
1515
let v: &[u128] = &[0; 10];
1616
let v_0: *const u128 = &v[0];
1717
let high_offset = usize::MAX / (std::mem::size_of::<u128>() * 4);
18-
unsafe {
19-
let v_wrap: *const u128 = v_0.wrapping_add(high_offset);
20-
// This should trigger UB!!
21-
let wrapped_offset = unsafe { v_wrap.offset_from(v_0) };
22-
// Without UB detection, the offsets are the same, but CBMC pointer arithmetic
23-
// would "wrap around" making this incorrect
24-
// https://github.com/model-checking/kani/issues/1150
25-
assert!(high_offset == wrapped_offset.try_into().unwrap());
26-
}
18+
let v_wrap: *const u128 = v_0.wrapping_add(high_offset);
19+
// FIX-ME: This should trigger UB!!
20+
// https://github.com/model-checking/kani/issues/3756
21+
let wrapped_offset = unsafe { v_wrap.offset_from(v_0) };
22+
// Without UB detection, the offsets are the same, but CBMC pointer arithmetic
23+
// would "wrap around" making this incorrect
24+
// https://github.com/model-checking/kani/issues/1150
25+
assert!(high_offset == wrapped_offset.try_into().unwrap());
2726
}
2827

2928
/// This harness is similar to the `original_harness`, but we replace the `offset_from` with
@@ -33,27 +32,18 @@ fn harness_without_ub() {
3332
let v: &[u128] = &[0; 10];
3433
let v_0: *const u128 = &v[0];
3534
let high_offset = usize::MAX / (size_of::<u128>() * 4);
36-
unsafe {
37-
let v_wrap: *const u128 = v_0.wrapping_add(high_offset);
38-
// The only way to compute offset of pointers out of bounds is to convert them to integers.
39-
let wrapped_offset = (v_wrap.addr() - v_0.addr()) / size_of::<u128>();
40-
// Now this should work
41-
assert_eq!(high_offset, wrapped_offset);
42-
}
35+
let v_wrap: *const u128 = v_0.wrapping_add(high_offset);
36+
// The only way to compute offset of pointers out of bounds is to convert them to integers.
37+
let wrapped_offset = (v_wrap.addr() - v_0.addr()) / size_of::<u128>();
38+
// Now this should work
39+
assert_eq!(high_offset, wrapped_offset);
4340
}
4441

42+
/// Check that wrapping offset by `usize::MAX + 1` bytes will result in the same base pointer.
4543
#[kani::proof]
46-
fn check_wrap_ptr_max() {
44+
fn check_wrap_around_ptr() {
4745
let v: &[u128] = &[0; 10];
4846
let orig_ptr: *const u128 = &v[0];
4947
let new_ptr: *const u128 = orig_ptr.wrapping_byte_add(usize::MAX).wrapping_byte_add(1);
5048
assert_eq!(orig_ptr as usize, new_ptr as usize);
5149
}
52-
53-
#[kani::proof]
54-
fn check_wrap_ptr_10_bits() {
55-
let v: &[u128] = &[0; 10];
56-
let orig_ptr: *const u128 = &v[0];
57-
let new_ptr: *const u128 = orig_ptr.wrapping_byte_add(1 << 63);
58-
assert_ne!(orig_ptr as usize, new_ptr as usize);
59-
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
4+
//! Testcase for issue [#1150](https://github.com/model-checking/kani/issues/1150) that shows
5+
//! bug with wrapping offset operations in Kani.
6+
7+
/// This harness shows the issue with the current implementation of wrapping offset.
8+
///
9+
/// Invoking `wrapping_byte_offset` should return a pointer that is different from the original
10+
/// pointer if the offset value is not 0.
11+
/// See issue [#1150](https://github.com/model-checking/kani/issues/1150).
12+
#[kani::proof]
13+
fn fixme_incorrect_wrapping_offset() {
14+
let ptr: *const u8 = &0u8;
15+
let offset = kani::any_where(|v: &isize| *v != 0);
16+
let new_ptr = ptr.wrapping_byte_offset(offset);
17+
assert_ne!(ptr, new_ptr, "Expected new_ptr to be different than ptr");
18+
}

tests/kani/Vectors/vector_extend_bytes.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
// Copyright Kani Contributors
22
// SPDX-License-Identifier: Apache-2.0 OR MIT
33

4-
//! Check that we propertly handle `Vec::extend` with a constant byte slice.
4+
//! Check that we properly handle `Vec::extend` with a constant byte slice.
55
//! This used to fail previously (see
66
//! https://github.com/model-checking/kani/issues/2656).
77
8+
#[kani::unwind(4)]
89
#[kani::proof]
910
fn check_extend_const_byte_slice() {
1011
const MY_CONSTANT: &[u8] = b"Hi";

0 commit comments

Comments
 (0)