Skip to content

Commit c0b3286

Browse files
authored
Document behavior of checked_size_of_raw and is_inbounds (#3956)
Resolves #3947 Explicitly document behavior of checked_size_of_raw and is_inbounds with respect to isize::MAX to clarify safety guarantees. By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 and MIT licenses.
1 parent 7d7fca2 commit c0b3286

File tree

3 files changed

+34
-1
lines changed

3 files changed

+34
-1
lines changed

library/kani_core/src/mem.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,10 @@ macro_rules! kani_mem {
129129

130130
/// Compute the size of the val pointed to if it is safe to do so.
131131
///
132-
/// Return `None` if an overflow would occur, or if alignment is not power of two.
132+
/// Returns `None` if:
133+
/// - An overflow occurs during the size computation.
134+
/// - The pointer’s alignment is not a power of two.
135+
/// - The computed size exceeds `isize::MAX` (the maximum safe Rust allocation size).
133136
/// TODO: Optimize this if T is sized.
134137
#[kanitool::fn_marker = "CheckedSizeOfIntrinsic"]
135138
pub fn checked_size_of_raw<T: ?Sized>(ptr: *const T) -> Option<usize> {
@@ -166,6 +169,14 @@ macro_rules! kani_mem {
166169
/// Checks that `ptr` points to an allocation that can hold data of size calculated from `T`.
167170
///
168171
/// This will panic if `ptr` points to an invalid `non_null`
172+
/// Returns `false` if:
173+
/// - The computed size overflows.
174+
/// - The computed size exceeds `isize::MAX`.
175+
/// - The pointer is null (except for zero-sized types).
176+
/// - The pointer references unallocated memory.
177+
///
178+
/// This function aligns with Rust's memory safety requirements, which restrict valid allocations
179+
/// to sizes no larger than `isize::MAX`.
169180
fn is_inbounds<T: ?Sized>(ptr: *const T) -> bool {
170181
// If size overflows, then pointer cannot be inbounds.
171182
let Some(sz) = checked_size_of_raw(ptr) else { return false };
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Complete - 1 successfully verified harnesses, 0 failures, 1 total.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright Kani Contributors
2+
// SPDX-License-Identifier: Apache-2.0 OR MIT
3+
// kani-flags: -Z mem-predicates
4+
#![feature(ptr_metadata)]
5+
6+
extern crate kani;
7+
8+
mod size {
9+
use super::*;
10+
11+
#[kani::proof]
12+
fn verify_checked_size_of_raw_exceeds_isize_max() {
13+
let len_exceeding_isize_max = (isize::MAX as usize) + 1;
14+
let data_ptr: *const [u8] =
15+
core::ptr::from_raw_parts(core::ptr::null::<u8>(), len_exceeding_isize_max);
16+
17+
let size = kani::mem::checked_size_of_raw(data_ptr);
18+
19+
assert!(size.is_none());
20+
}
21+
}

0 commit comments

Comments
 (0)