Auto merge of #3974 - RalfJung:check_min_arg_count, r=RalfJung
use new check_min_arg_count helper in more places
This commit is contained in:
commit
eb5ca5f53c
3 changed files with 17 additions and 35 deletions
|
@ -5,6 +5,7 @@ use rustc_span::{BytePos, Loc, Symbol, hygiene};
|
||||||
use rustc_target::abi::Size;
|
use rustc_target::abi::Size;
|
||||||
use rustc_target::spec::abi::Abi;
|
use rustc_target::spec::abi::Abi;
|
||||||
|
|
||||||
|
use crate::helpers::check_min_arg_count;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
|
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 this = self.eval_context_mut();
|
||||||
let tcx = this.tcx;
|
let tcx = this.tcx;
|
||||||
|
|
||||||
let flags = if let Some(flags_op) = args.first() {
|
let [flags] = check_min_arg_count("miri_get_backtrace", args)?;
|
||||||
this.read_scalar(flags_op)?.to_u64()?
|
let flags = this.read_scalar(flags)?.to_u64()?;
|
||||||
} else {
|
|
||||||
throw_ub_format!("expected at least 1 argument")
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
for frame in this.active_thread_stack().iter().rev() {
|
for frame in this.active_thread_stack().iter().rev() {
|
||||||
|
|
|
@ -150,7 +150,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
|
||||||
}
|
}
|
||||||
// `futex` is used by some synchronization primitives.
|
// `futex` is used by some synchronization primitives.
|
||||||
num if num == sys_futex => {
|
num if num == sys_futex => {
|
||||||
futex(this, &args[1..], dest)?;
|
futex(this, args, dest)?;
|
||||||
}
|
}
|
||||||
num if num == sys_eventfd2 => {
|
num if num == sys_eventfd2 => {
|
||||||
let [_, initval, flags] =
|
let [_, initval, flags] =
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
use crate::helpers::check_min_arg_count;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
/// Implementation of the SYS_futex syscall.
|
/// 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>(
|
pub fn futex<'tcx>(
|
||||||
this: &mut MiriInterpCx<'tcx>,
|
this: &mut MiriInterpCx<'tcx>,
|
||||||
args: &[OpTy<'tcx>],
|
args: &[OpTy<'tcx>],
|
||||||
|
@ -15,12 +16,7 @@ pub fn futex<'tcx>(
|
||||||
// may or may not be left out from the `syscall()` call.
|
// 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
|
// Therefore we don't use `check_arg_count` here, but only check for the
|
||||||
// number of arguments to fall within a range.
|
// number of arguments to fall within a range.
|
||||||
let [addr, op, val, ..] = args else {
|
let [_, addr, op, val] = check_min_arg_count("`syscall(SYS_futex, ...)`", args)?;
|
||||||
throw_ub_format!(
|
|
||||||
"incorrect number of arguments for `futex` syscall: got {}, expected at least 3",
|
|
||||||
args.len()
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
// The first three arguments (after the syscall number itself) are the same to all futex operations:
|
// The first three arguments (after the syscall number itself) are the same to all futex operations:
|
||||||
// (int *addr, int op, int val).
|
// (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 => {
|
op if op & !futex_realtime == futex_wait || op & !futex_realtime == futex_wait_bitset => {
|
||||||
let wait_bitset = op & !futex_realtime == futex_wait_bitset;
|
let wait_bitset = op & !futex_realtime == futex_wait_bitset;
|
||||||
|
|
||||||
let bitset = if wait_bitset {
|
let (timeout, bitset) = if wait_bitset {
|
||||||
let [_, _, _, timeout, uaddr2, bitset, ..] = args else {
|
let [_, _, _, _, timeout, uaddr2, bitset] =
|
||||||
throw_ub_format!(
|
check_min_arg_count("`syscall(SYS_futex, FUTEX_WAIT_BITSET, ...)`", args)?;
|
||||||
"incorrect number of arguments for `futex` syscall with `op=FUTEX_WAIT_BITSET`: got {}, expected at least 6",
|
|
||||||
args.len()
|
|
||||||
);
|
|
||||||
};
|
|
||||||
let _timeout = this.read_pointer(timeout)?;
|
let _timeout = this.read_pointer(timeout)?;
|
||||||
let _uaddr2 = this.read_pointer(uaddr2)?;
|
let _uaddr2 = this.read_pointer(uaddr2)?;
|
||||||
this.read_scalar(bitset)?.to_u32()?
|
(timeout, this.read_scalar(bitset)?.to_u32()?)
|
||||||
} else {
|
} else {
|
||||||
if args.len() < 4 {
|
let [_, _, _, _, timeout] =
|
||||||
throw_ub_format!(
|
check_min_arg_count("`syscall(SYS_futex, FUTEX_WAIT, ...)`", args)?;
|
||||||
"incorrect number of arguments for `futex` syscall with `op=FUTEX_WAIT`: got {}, expected at least 4",
|
(timeout, u32::MAX)
|
||||||
args.len()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
u32::MAX
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if bitset == 0 {
|
if bitset == 0 {
|
||||||
|
@ -80,7 +68,7 @@ pub fn futex<'tcx>(
|
||||||
return interp_ok(());
|
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())? {
|
let timeout = if this.ptr_is_null(timeout.ptr())? {
|
||||||
None
|
None
|
||||||
} else {
|
} 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.
|
// 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 => {
|
op if op == futex_wake || op == futex_wake_bitset => {
|
||||||
let bitset = if op == futex_wake_bitset {
|
let bitset = if op == futex_wake_bitset {
|
||||||
let [_, _, _, timeout, uaddr2, bitset, ..] = args else {
|
let [_, _, _, _, timeout, uaddr2, bitset] =
|
||||||
throw_ub_format!(
|
check_min_arg_count("`syscall(SYS_futex, FUTEX_WAKE_BITSET, ...)`", args)?;
|
||||||
"incorrect number of arguments for `futex` syscall with `op=FUTEX_WAKE_BITSET`: got {}, expected at least 6",
|
|
||||||
args.len()
|
|
||||||
);
|
|
||||||
};
|
|
||||||
let _timeout = this.read_pointer(timeout)?;
|
let _timeout = this.read_pointer(timeout)?;
|
||||||
let _uaddr2 = this.read_pointer(uaddr2)?;
|
let _uaddr2 = this.read_pointer(uaddr2)?;
|
||||||
this.read_scalar(bitset)?.to_u32()?
|
this.read_scalar(bitset)?.to_u32()?
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue