-
Notifications
You must be signed in to change notification settings - Fork 101
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add UB checks for ptr_offset_from* intrinsics (#3757)
Add a new model for `ptr_offset_from` and `ptr_offset_from_unsigned` intrinsics that check allocation and address order. Resolves #3756 By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses. --------- Co-authored-by: Michael Tautschnig <[email protected]> Co-authored-by: Carolyn Zech <[email protected]>
- Loading branch information
1 parent
52cb262
commit 4d477f6
Showing
16 changed files
with
275 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1 @@ | ||
FAILURE\ | ||
"same object violation" | ||
Failed Checks: Offset result and original pointer should point to the same allocation |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
Failed Checks: attempt to compute unsigned offset with negative distance | ||
Failed Checks: Expected non-negative distance between pointers |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
Checking harness check_offset_from_same_dangling... | ||
VERIFICATION:- SUCCESSFUL | ||
|
||
Checking harness check_offset_from_unit_panic... | ||
Failed Checks: assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize | ||
VERIFICATION:- SUCCESSFUL (encountered one or more panics as expected) | ||
|
||
Checking harness check_offset_from_diff_alloc... | ||
Failed Checks: Offset result and original pointer should point to the same allocation | ||
VERIFICATION:- FAILED | ||
|
||
Checking harness check_offset_from_oob_ptr... | ||
Failed Checks: Offset result and original pointer should point to the same allocation | ||
VERIFICATION:- FAILED (encountered failures other than panics, which were unexpected) | ||
|
||
Verification failed for - check_offset_from_diff_alloc | ||
Verification failed for - check_offset_from_oob_ptr | ||
Complete - 2 successfully verified harnesses, 2 failures, 4 total. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
//! Check that Kani offset operations correctly detect out-of-bound access. | ||
/// Verification should fail because safety violation is not a regular panic. | ||
#[kani::proof] | ||
#[kani::should_panic] | ||
fn check_offset_from_oob_ptr() { | ||
let val = 10u128; | ||
let ptr: *const u128 = &val; | ||
let ptr_oob: *const u128 = ptr.wrapping_add(10); | ||
// SAFETY: This is not safe! | ||
let _offset = unsafe { ptr_oob.offset_from(ptr) }; | ||
} | ||
|
||
#[kani::proof] | ||
fn check_offset_from_diff_alloc() { | ||
let val1 = 10u128; | ||
let val2 = 0u128; | ||
let ptr1: *const u128 = &val1; | ||
let ptr2: *const u128 = &val2; | ||
// SAFETY: This is not safe! | ||
let offset = unsafe { ptr1.offset_from(ptr2) }; | ||
assert!(offset != 0); | ||
} | ||
|
||
#[kani::proof] | ||
#[kani::should_panic] | ||
fn check_offset_from_unit_panic() { | ||
let val1 = kani::any(); | ||
let val2 = kani::any(); | ||
let ptr1: *const () = &val1 as *const _ as *const (); | ||
let ptr2: *const () = &val2 as *const _ as *const (); | ||
// SAFETY: This is safe but will panic... | ||
let _offset = unsafe { ptr1.offset_from(ptr2) }; | ||
} | ||
|
||
#[kani::proof] | ||
fn check_offset_from_same_dangling() { | ||
let val = 10u128; | ||
let ptr: *const u128 = &val; | ||
let ptr_oob_1: *const u128 = ptr.wrapping_add(10); | ||
let ptr_oob_2: *const u128 = ptr.wrapping_add(5).wrapping_add(5); | ||
// SAFETY: This is safe since the pointer is the same! | ||
let offset = unsafe { ptr_oob_1.offset_from(ptr_oob_2) }; | ||
assert_eq!(offset, 0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
Checking harness check_sub_ptr_same_dangling... | ||
VERIFICATION:- SUCCESSFUL | ||
|
||
Checking harness check_sub_ptr_unit_panic... | ||
Failed Checks: assertion failed: 0 < pointee_size && pointee_size <= isize::MAX as usize | ||
VERIFICATION:- SUCCESSFUL (encountered one or more panics as expected) | ||
|
||
Checking harness check_sub_ptr_negative_result... | ||
Failed Checks: Expected non-negative distance between pointers | ||
VERIFICATION:- FAILED | ||
|
||
Checking harness check_sub_ptr_diff_alloc... | ||
Failed Checks: Offset result and original pointer should point to the same allocation | ||
VERIFICATION:- FAILED | ||
|
||
Checking harness check_sub_ptr_oob_ptr... | ||
Failed Checks: Offset result and original pointer should point to the same allocation | ||
VERIFICATION:- FAILED | ||
|
||
Checking harness check_sub_ptr_self_oob... | ||
Failed Checks: Offset result and original pointer should point to the same allocation | ||
VERIFICATION:- FAILED | ||
|
||
Summary: | ||
Verification failed for - check_sub_ptr_negative_result | ||
Verification failed for - check_sub_ptr_diff_alloc | ||
Verification failed for - check_sub_ptr_oob_ptr | ||
Verification failed for - check_sub_ptr_self_oob | ||
Complete - 2 successfully verified harnesses, 4 failures, 6 total. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
// Copyright Kani Contributors | ||
// SPDX-License-Identifier: Apache-2.0 OR MIT | ||
//! Check that Kani can detect UB due to `sub_ptr` with out-of-bounds pointer or wrong order. | ||
#![feature(ptr_sub_ptr)] | ||
|
||
#[kani::proof] | ||
fn check_sub_ptr_self_oob() { | ||
let val = 10u128; | ||
let ptr: *const u128 = &val; | ||
let ptr_oob: *const u128 = ptr.wrapping_add(10); | ||
// SAFETY: This is not safe! | ||
let _offset = unsafe { ptr_oob.sub_ptr(ptr) }; | ||
} | ||
|
||
#[kani::proof] | ||
fn check_sub_ptr_oob_ptr() { | ||
let val = 10u128; | ||
let ptr: *const u128 = &val; | ||
let ptr_oob: *const u128 = ptr.wrapping_sub(10); | ||
// SAFETY: This is not safe! | ||
let _offset = unsafe { ptr.sub_ptr(ptr_oob) }; | ||
} | ||
|
||
#[kani::proof] | ||
fn check_sub_ptr_diff_alloc() { | ||
let val1 = kani::any(); | ||
let val2 = kani::any(); | ||
let ptr1: *const u128 = &val1; | ||
let ptr2: *const u128 = &val2; | ||
// SAFETY: This is not safe! | ||
let _offset = unsafe { ptr1.sub_ptr(ptr2) }; | ||
} | ||
|
||
#[kani::proof] | ||
fn check_sub_ptr_negative_result() { | ||
let val: [u8; 10] = kani::any(); | ||
let ptr_first: *const _ = &val[0]; | ||
let ptr_last: *const _ = &val[9]; | ||
// SAFETY: This is safe! | ||
let offset_ok = unsafe { ptr_last.sub_ptr(ptr_first) }; | ||
|
||
// SAFETY: This is not safe! | ||
let offset_not_ok = unsafe { ptr_first.sub_ptr(ptr_last) }; | ||
|
||
// Just use the result. | ||
assert!(offset_ok != offset_not_ok); | ||
} | ||
|
||
#[kani::proof] | ||
#[kani::should_panic] | ||
fn check_sub_ptr_unit_panic() { | ||
let val1 = kani::any(); | ||
let val2 = kani::any(); | ||
let ptr1: *const () = &val1 as *const _ as *const (); | ||
let ptr2: *const () = &val2 as *const _ as *const (); | ||
// SAFETY: This is safe but will panic... | ||
let _offset = unsafe { ptr1.sub_ptr(ptr2) }; | ||
} | ||
|
||
#[kani::proof] | ||
fn check_sub_ptr_same_dangling() { | ||
let val = 10u128; | ||
let ptr: *const u128 = &val; | ||
let ptr_oob_1: *const u128 = ptr.wrapping_add(10); | ||
let ptr_oob_2: *const u128 = ptr.wrapping_add(5).wrapping_add(5); | ||
// SAFETY: This is safe since the pointer is the same! | ||
let offset = unsafe { ptr_oob_1.sub_ptr(ptr_oob_2) }; | ||
assert_eq!(offset, 0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Failed Checks: Expected the distance between the pointers, in bytes, to be a | ||
multiple of the size of `T` | ||
VERIFICATION:- FAILED |
Oops, something went wrong.