Skip to content

Commit e1964fe

Browse files
committed
Auto merge of #3974 - RalfJung:check_min_arg_count, r=RalfJung
use new check_min_arg_count helper in more places
2 parents 23ff2ea + 72aebf6 commit e1964fe

File tree

3 files changed

+17
-35
lines changed

3 files changed

+17
-35
lines changed

src/shims/backtrace.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use rustc_span::{BytePos, Loc, Symbol, hygiene};
55
use rustc_target::abi::Size;
66
use rustc_target::spec::abi::Abi;
77

8+
use crate::helpers::check_min_arg_count;
89
use crate::*;
910

1011
impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
@@ -39,11 +40,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
3940
let this = self.eval_context_mut();
4041
let tcx = this.tcx;
4142

42-
let flags = if let Some(flags_op) = args.first() {
43-
this.read_scalar(flags_op)?.to_u64()?
44-
} else {
45-
throw_ub_format!("expected at least 1 argument")
46-
};
43+
let [flags] = check_min_arg_count("miri_get_backtrace", args)?;
44+
let flags = this.read_scalar(flags)?.to_u64()?;
4745

4846
let mut data = Vec::new();
4947
for frame in this.active_thread_stack().iter().rev() {

src/shims/unix/linux/foreign_items.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
150150
}
151151
// `futex` is used by some synchronization primitives.
152152
num if num == sys_futex => {
153-
futex(this, &args[1..], dest)?;
153+
futex(this, args, dest)?;
154154
}
155155
num if num == sys_eventfd2 => {
156156
let [_, initval, flags] =

src/shims/unix/linux/sync.rs

+13-29
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
use crate::helpers::check_min_arg_count;
12
use crate::*;
23

34
/// Implementation of the SYS_futex syscall.
4-
/// `args` is the arguments *after* the syscall number.
5+
/// `args` is the arguments *including* the syscall number.
56
pub fn futex<'tcx>(
67
this: &mut MiriInterpCx<'tcx>,
78
args: &[OpTy<'tcx>],
@@ -15,12 +16,7 @@ pub fn futex<'tcx>(
1516
// may or may not be left out from the `syscall()` call.
1617
// Therefore we don't use `check_arg_count` here, but only check for the
1718
// number of arguments to fall within a range.
18-
let [addr, op, val, ..] = args else {
19-
throw_ub_format!(
20-
"incorrect number of arguments for `futex` syscall: got {}, expected at least 3",
21-
args.len()
22-
);
23-
};
19+
let [_, addr, op, val] = check_min_arg_count("`syscall(SYS_futex, ...)`", args)?;
2420

2521
// The first three arguments (after the syscall number itself) are the same to all futex operations:
2622
// (int *addr, int op, int val).
@@ -54,24 +50,16 @@ pub fn futex<'tcx>(
5450
op if op & !futex_realtime == futex_wait || op & !futex_realtime == futex_wait_bitset => {
5551
let wait_bitset = op & !futex_realtime == futex_wait_bitset;
5652

57-
let bitset = if wait_bitset {
58-
let [_, _, _, timeout, uaddr2, bitset, ..] = args else {
59-
throw_ub_format!(
60-
"incorrect number of arguments for `futex` syscall with `op=FUTEX_WAIT_BITSET`: got {}, expected at least 6",
61-
args.len()
62-
);
63-
};
53+
let (timeout, bitset) = if wait_bitset {
54+
let [_, _, _, _, timeout, uaddr2, bitset] =
55+
check_min_arg_count("`syscall(SYS_futex, FUTEX_WAIT_BITSET, ...)`", args)?;
6456
let _timeout = this.read_pointer(timeout)?;
6557
let _uaddr2 = this.read_pointer(uaddr2)?;
66-
this.read_scalar(bitset)?.to_u32()?
58+
(timeout, this.read_scalar(bitset)?.to_u32()?)
6759
} else {
68-
if args.len() < 4 {
69-
throw_ub_format!(
70-
"incorrect number of arguments for `futex` syscall with `op=FUTEX_WAIT`: got {}, expected at least 4",
71-
args.len()
72-
);
73-
}
74-
u32::MAX
60+
let [_, _, _, _, timeout] =
61+
check_min_arg_count("`syscall(SYS_futex, FUTEX_WAIT, ...)`", args)?;
62+
(timeout, u32::MAX)
7563
};
7664

7765
if bitset == 0 {
@@ -80,7 +68,7 @@ pub fn futex<'tcx>(
8068
return interp_ok(());
8169
}
8270

83-
let timeout = this.deref_pointer_as(&args[3], this.libc_ty_layout("timespec"))?;
71+
let timeout = this.deref_pointer_as(timeout, this.libc_ty_layout("timespec"))?;
8472
let timeout = if this.ptr_is_null(timeout.ptr())? {
8573
None
8674
} else {
@@ -183,12 +171,8 @@ pub fn futex<'tcx>(
183171
// Same as FUTEX_WAKE, but allows you to specify a bitset to select which threads to wake up.
184172
op if op == futex_wake || op == futex_wake_bitset => {
185173
let bitset = if op == futex_wake_bitset {
186-
let [_, _, _, timeout, uaddr2, bitset, ..] = args else {
187-
throw_ub_format!(
188-
"incorrect number of arguments for `futex` syscall with `op=FUTEX_WAKE_BITSET`: got {}, expected at least 6",
189-
args.len()
190-
);
191-
};
174+
let [_, _, _, _, timeout, uaddr2, bitset] =
175+
check_min_arg_count("`syscall(SYS_futex, FUTEX_WAKE_BITSET, ...)`", args)?;
192176
let _timeout = this.read_pointer(timeout)?;
193177
let _uaddr2 = this.read_pointer(uaddr2)?;
194178
this.read_scalar(bitset)?.to_u32()?

0 commit comments

Comments
 (0)