diff options
| author | Dylan DPC <dylan.dpc@gmail.com> | 2020-04-26 21:02:39 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-26 21:02:39 +0200 |
| commit | b2a8a8a0f882728809a99841787cd8f745768f5f (patch) | |
| tree | 8b8c2a0ef1c5462cceccfead3db274faa274ff55 | |
| parent | d1287746cd16c793131969b623e39956d783f545 (diff) | |
| parent | c8d8c42d1ce10d945bcd8cbff3ac9858fc909abc (diff) | |
| download | rust-b2a8a8a0f882728809a99841787cd8f745768f5f.tar.gz rust-b2a8a8a0f882728809a99841787cd8f745768f5f.zip | |
Rollup merge of #71569 - samrat:miri-ub-on-size-mismatch, r=RalfJung
[miri] Throw UB if target size and data size don't match
Issue: https://github.com/rust-lang/miri/issues/1355
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), return undefined behaviour from Miri when [converting the argument into machine_usize](https://github.com/rust-lang/miri/blob/master/src/shims/foreign_items.rs#L200)
| -rw-r--r-- | src/librustc_middle/mir/interpret/error.rs | 10 | ||||
| -rw-r--r-- | src/librustc_middle/mir/interpret/value.rs | 7 |
2 files changed, 16 insertions, 1 deletions
diff --git a/src/librustc_middle/mir/interpret/error.rs b/src/librustc_middle/mir/interpret/error.rs index 4b5c6177b25..e6557c9fbd5 100644 --- a/src/librustc_middle/mir/interpret/error.rs +++ b/src/librustc_middle/mir/interpret/error.rs @@ -360,6 +360,11 @@ pub enum UndefinedBehaviorInfo { InvalidUndefBytes(Option<Pointer>), /// Working with a local that is not currently live. DeadLocal, + /// Data size is not equal to target size. + ScalarSizeMismatch { + target_size: u64, + data_size: u64, + }, } impl fmt::Debug for UndefinedBehaviorInfo { @@ -421,6 +426,11 @@ impl fmt::Debug for UndefinedBehaviorInfo { "using uninitialized data, but this operation requires initialized memory" ), DeadLocal => write!(f, "accessing a dead local variable"), + ScalarSizeMismatch { target_size, data_size } => write!( + f, + "scalar 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..6e013f75ed7 100644 --- a/src/librustc_middle/mir/interpret/value.rs +++ b/src/librustc_middle/mir/interpret/value.rs @@ -393,7 +393,12 @@ impl<'tcx, Tag> Scalar<Tag> { 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!(ScalarSizeMismatch { + target_size: target_size.bytes(), + data_size: u64::from(size), + }); + } Scalar::check_data(data, size); Ok(data) } |
