From: Samrat Man Singh Date: Sun, 26 Apr 2020 03:28:22 +0000 (+0530) Subject: [miri] Throw UB if target size and data size don't match X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=91462db9f1c1b5db941c22efb64e7ec01d472911;p=rust.git [miri] Throw UB if target size and data size don't match If an extern C function is defined as ``` extern "C" { fn malloc(size: u32) -> *mut std::ffi::c_void; } ``` on a 64-bit machine(ie. pointer sizes don't match), throw an undefined behaviour. --- diff --git a/src/librustc_middle/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs index 2510dbcea0b..71a9382bc65 100644 --- a/src/librustc_middle/mir/interpret/error.rs +++ b/src/librustc_middle/mir/interpret/error.rs @@ -361,6 +361,11 @@ pub enum UndefinedBehaviorInfo { InvalidUndefBytes(Option), /// Working with a local that is not currently live. DeadLocal, + /// Data size is not equal to target size + ArgumentSizeMismatch { + target_size: u64, + data_size: u64, + }, } impl fmt::Debug for UndefinedBehaviorInfo { @@ -422,6 +427,11 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { "using uninitialized data, but this operation requires initialized memory" ), DeadLocal => write!(f, "accessing a dead local variable"), + ArgumentSizeMismatch { target_size, data_size } => write!( + f, + "argument size mismatch: expected {} bytes but got {} bytes instead", + target_size, data_size + ), } } } diff --git a/src/librustc_middle/mir/interpret/value.rs b/src/librustc_middle/mir/interpret/value.rs index f3c1c87dad4..c11e5001508 100644 --- a/src/librustc_middle/mir/interpret/value.rs +++ b/src/librustc_middle/mir/interpret/value.rs @@ -393,7 +393,12 @@ fn to_bits(self, target_size: Size) -> InterpResult<'tcx, u128> { assert_ne!(target_size.bytes(), 0, "you should never look at the bits of a ZST"); match self { Scalar::Raw { data, size } => { - assert_eq!(target_size.bytes(), u64::from(size)); + if target_size.bytes() != u64::from(size) { + throw_ub!(ArgumentSizeMismatch { + target_size: target_size.bytes(), + data_size: u64::from(size) + }); + } Scalar::check_data(data, size); Ok(data) }