From 413ea993deebdb321db71ac8a9187e13e9990370 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 14 Oct 2024 23:37:03 +0200 Subject: [PATCH] use new check_min_arg_count helper in more places --- src/tools/miri/src/shims/backtrace.rs | 8 ++-- .../src/shims/unix/linux/foreign_items.rs | 2 +- src/tools/miri/src/shims/unix/linux/sync.rs | 42 ++++++------------- 3 files changed, 17 insertions(+), 35 deletions(-) diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs index 25afda4edc853..ae2cdaa8d57ad 100644 --- a/src/tools/miri/src/shims/backtrace.rs +++ b/src/tools/miri/src/shims/backtrace.rs @@ -5,6 +5,7 @@ use rustc_span::{BytePos, Loc, Symbol, hygiene}; use rustc_target::abi::Size; use rustc_target::spec::abi::Abi; +use crate::helpers::check_min_arg_count; use crate::*; impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {} @@ -39,11 +40,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { let this = self.eval_context_mut(); let tcx = this.tcx; - let flags = if let Some(flags_op) = args.first() { - this.read_scalar(flags_op)?.to_u64()? - } else { - throw_ub_format!("expected at least 1 argument") - }; + let [flags] = check_min_arg_count("miri_get_backtrace", args)?; + let flags = this.read_scalar(flags)?.to_u64()?; let mut data = Vec::new(); for frame in this.active_thread_stack().iter().rev() { 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 6c8345652c269..e73bde1ddb660 100644 --- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs +++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs @@ -150,7 +150,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> { } // `futex` is used by some synchronization primitives. num if num == sys_futex => { - futex(this, &args[1..], dest)?; + futex(this, args, dest)?; } num if num == sys_eventfd2 => { let [_, initval, flags] = diff --git a/src/tools/miri/src/shims/unix/linux/sync.rs b/src/tools/miri/src/shims/unix/linux/sync.rs index 5833ec64fc68f..941011bfac640 100644 --- a/src/tools/miri/src/shims/unix/linux/sync.rs +++ b/src/tools/miri/src/shims/unix/linux/sync.rs @@ -1,7 +1,8 @@ +use crate::helpers::check_min_arg_count; use crate::*; /// Implementation of the SYS_futex syscall. -/// `args` is the arguments *after* the syscall number. +/// `args` is the arguments *including* the syscall number. pub fn futex<'tcx>( this: &mut MiriInterpCx<'tcx>, args: &[OpTy<'tcx>], @@ -15,12 +16,7 @@ pub fn futex<'tcx>( // may or may not be left out from the `syscall()` call. // Therefore we don't use `check_arg_count` here, but only check for the // number of arguments to fall within a range. - let [addr, op, val, ..] = args else { - throw_ub_format!( - "incorrect number of arguments for `futex` syscall: got {}, expected at least 3", - args.len() - ); - }; + let [_, addr, op, val] = check_min_arg_count("`syscall(SYS_futex, ...)`", args)?; // The first three arguments (after the syscall number itself) are the same to all futex operations: // (int *addr, int op, int val). @@ -54,24 +50,16 @@ pub fn futex<'tcx>( op if op & !futex_realtime == futex_wait || op & !futex_realtime == futex_wait_bitset => { let wait_bitset = op & !futex_realtime == futex_wait_bitset; - let bitset = if wait_bitset { - let [_, _, _, timeout, uaddr2, bitset, ..] = args else { - throw_ub_format!( - "incorrect number of arguments for `futex` syscall with `op=FUTEX_WAIT_BITSET`: got {}, expected at least 6", - args.len() - ); - }; + let (timeout, bitset) = if wait_bitset { + let [_, _, _, _, timeout, uaddr2, bitset] = + check_min_arg_count("`syscall(SYS_futex, FUTEX_WAIT_BITSET, ...)`", args)?; let _timeout = this.read_pointer(timeout)?; let _uaddr2 = this.read_pointer(uaddr2)?; - this.read_scalar(bitset)?.to_u32()? + (timeout, this.read_scalar(bitset)?.to_u32()?) } else { - if args.len() < 4 { - throw_ub_format!( - "incorrect number of arguments for `futex` syscall with `op=FUTEX_WAIT`: got {}, expected at least 4", - args.len() - ); - } - u32::MAX + let [_, _, _, _, timeout] = + check_min_arg_count("`syscall(SYS_futex, FUTEX_WAIT, ...)`", args)?; + (timeout, u32::MAX) }; if bitset == 0 { @@ -80,7 +68,7 @@ pub fn futex<'tcx>( return interp_ok(()); } - let timeout = this.deref_pointer_as(&args[3], this.libc_ty_layout("timespec"))?; + let timeout = this.deref_pointer_as(timeout, this.libc_ty_layout("timespec"))?; let timeout = if this.ptr_is_null(timeout.ptr())? { None } else { @@ -183,12 +171,8 @@ pub fn futex<'tcx>( // Same as FUTEX_WAKE, but allows you to specify a bitset to select which threads to wake up. op if op == futex_wake || op == futex_wake_bitset => { let bitset = if op == futex_wake_bitset { - let [_, _, _, timeout, uaddr2, bitset, ..] = args else { - throw_ub_format!( - "incorrect number of arguments for `futex` syscall with `op=FUTEX_WAKE_BITSET`: got {}, expected at least 6", - args.len() - ); - }; + let [_, _, _, _, timeout, uaddr2, bitset] = + check_min_arg_count("`syscall(SYS_futex, FUTEX_WAKE_BITSET, ...)`", args)?; let _timeout = this.read_pointer(timeout)?; let _uaddr2 = this.read_pointer(uaddr2)?; this.read_scalar(bitset)?.to_u32()?