about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/tools/miri/src/helpers.rs5
-rw-r--r--src/tools/miri/src/shims/unix/linux/foreign_items.rs4
-rw-r--r--src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs14
-rw-r--r--src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr15
4 files changed, 36 insertions, 2 deletions
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index a26f12cdfb1..3815da9ad06 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -999,6 +999,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         &'a [OpTy<'tcx>; N]: TryFrom<&'a [OpTy<'tcx>]>,
     {
         self.check_abi_and_shim_symbol_clash(abi, exp_abi, link_name)?;
+        if abi.c_variadic {
+            throw_ub_format!(
+                "calling a non-variadic function with a variadic caller-side signature"
+            );
+        }
         check_arg_count(args)
     }
 
diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
index 10af245dcc0..f5da7b0170b 100644
--- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
@@ -133,8 +133,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(ptr, dest)?;
             }
             "mremap" => {
-                let [old_address, old_size, new_size, flags] =
-                    this.check_shim(abi, Conv::C, link_name, args)?;
+                let ([old_address, old_size, new_size, flags], _) =
+                    this.check_shim_variadic(abi, Conv::C, link_name, args)?;
                 let ptr = this.mremap(old_address, old_size, new_size, flags)?;
                 this.write_scalar(ptr, dest)?;
             }
diff --git a/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs
new file mode 100644
index 00000000000..515e467fb54
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.rs
@@ -0,0 +1,14 @@
+//@ignore-target: windows # No libc pipe on Windows
+
+// Declare a non-variadic function as variadic.
+extern "C" {
+    fn pipe(fds: *mut std::ffi::c_int, ...) -> std::ffi::c_int;
+}
+
+// Test the error caused by invoking non-vararg shim with a vararg import.
+fn main() {
+    let mut fds = [-1, -1];
+    let res = unsafe { pipe(fds.as_mut_ptr()) };
+    //~^ ERROR: calling a non-variadic function with a variadic caller-side signature
+    assert_eq!(res, 0);
+}
diff --git a/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr
new file mode 100644
index 00000000000..2782f3b3269
--- /dev/null
+++ b/src/tools/miri/tests/fail/shims/vararg_caller_signature_mismatch.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: calling a non-variadic function with a variadic caller-side signature
+  --> tests/fail/shims/vararg_caller_signature_mismatch.rs:LL:CC
+   |
+LL |     let res = unsafe { pipe(fds.as_mut_ptr()) };
+   |                        ^^^^^^^^^^^^^^^^^^^^^^ calling a non-variadic function with a variadic caller-side signature
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at tests/fail/shims/vararg_caller_signature_mismatch.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to 1 previous error
+