Skip to content
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

Rust values can be up to isize::MAX in size #2043

Merged
merged 2 commits into from
Apr 1, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion rust-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
df20355fa9fa5e9fb89be4e4bfee8a643bb7a23e
297a8018b525c28ef10ee6a91d61954839b508b9
2 changes: 2 additions & 0 deletions src/shims/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let val_byte = this.read_scalar(val_byte)?.to_u8()?;
let ptr = this.read_pointer(ptr)?;
let count = this.read_scalar(count)?.to_machine_usize(this)?;
// `checked_mul` enforces a too small bound (the correct one would probably be machine_isize_max),
// but no actual allocation can be big enough for the difference to be noticeable.
let byte_count = ty_layout.size.checked_mul(count, this).ok_or_else(|| {
err_ub_format!("overflow computing total size of `{}`", intrinsic_name)
})?;
Expand Down
7 changes: 1 addition & 6 deletions tests/compile-fail/too-big-unsized.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,8 @@ struct MySlice {
tail: [u8],
}

#[cfg(target_pointer_width = "64")]
const TOO_BIG: usize = 1usize << 47;
#[cfg(target_pointer_width = "32")]
const TOO_BIG: usize = 1usize << 31;

fn main() { unsafe {
let ptr = Box::into_raw(Box::new(0u8));
// The slice part is actually not "too big", but together with the `prefix` field it is.
let _x: &MySlice = mem::transmute((ptr, TOO_BIG-1)); //~ ERROR: invalid reference metadata: total size is bigger than largest supported object
let _x: &MySlice = mem::transmute((ptr, isize::MAX as usize)); //~ ERROR: invalid reference metadata: total size is bigger than largest supported object
} }
9 changes: 9 additions & 0 deletions tests/run-pass/slices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#![feature(new_uninit)]
#![feature(slice_as_chunks)]
#![feature(slice_partition_dedup)]
#![feature(layout_for_ptr)]

use std::slice;

Expand Down Expand Up @@ -250,9 +251,17 @@ fn test_for_invalidated_pointers() {
buffer.copy_within(1.., 0);
}

fn large_raw_slice() {
let size = isize::MAX as usize;
// Creating a raw slice of size isize::MAX and asking for its size is okay.
let s = std::ptr::slice_from_raw_parts(1usize as *const u8, size);
assert_eq!(size, unsafe { std::mem::size_of_val_raw(s) });
}

fn main() {
slice_of_zst();
test_iter_ref_consistency();
uninit_slice();
test_for_invalidated_pointers();
large_raw_slice();
}