]> git.lizzy.rs Git - rust.git/commitdiff
[miri] Throw UB if target size and data size don't match
authorSamrat Man Singh <samratmansingh@gmail.com>
Sun, 26 Apr 2020 03:28:22 +0000 (08:58 +0530)
committerSamrat Man Singh <samratmansingh@gmail.com>
Sun, 26 Apr 2020 03:28:22 +0000 (08:58 +0530)
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.

src/librustc_middle/mir/interpret/error.rs
src/librustc_middle/mir/interpret/value.rs

index 2510dbcea0bdc1f40570f5221d1860d3d3e81073..71a9382bc65c476ead6906fbcdc190349d1642dc 100644 (file)
@@ -361,6 +361,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
+    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
+            ),
         }
     }
 }
index f3c1c87dad484b5aead0f759570aa4a332644ac2..c11e50015087bf3010536f8ce4d1fb36db88ab24 100644 (file)
@@ -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)
             }