Skip to content

Commit 08e6f28

Browse files
committed
treat prctl like a variadic function
1 parent 59ee672 commit 08e6f28

File tree

4 files changed

+29
-28
lines changed

4 files changed

+29
-28
lines changed

src/shims/posix/linux/foreign_items.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
106106

107107
// Threading
108108
"prctl" => {
109-
let &[ref option, ref arg2, ref arg3, ref arg4, ref arg5] =
110-
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
111-
let result = this.prctl(option, arg2, arg3, arg4, arg5)?;
109+
// prctl is variadic. (It is not documented like that in the manpage, but defined like that in the libc crate.)
110+
this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?;
111+
let result = this.prctl(args)?;
112112
this.write_scalar(Scalar::from_i32(result), dest)?;
113113
}
114114
"pthread_condattr_setclock" => {

src/shims/posix/thread.rs

+25-8
Original file line numberDiff line numberDiff line change
@@ -99,26 +99,43 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
9999

100100
fn prctl(
101101
&mut self,
102-
option: &OpTy<'tcx, Tag>,
103-
arg2: &OpTy<'tcx, Tag>,
104-
_arg3: &OpTy<'tcx, Tag>,
105-
_arg4: &OpTy<'tcx, Tag>,
106-
_arg5: &OpTy<'tcx, Tag>,
102+
args: &[OpTy<'tcx, Tag>],
107103
) -> InterpResult<'tcx, i32> {
108104
let this = self.eval_context_mut();
109105
this.assert_target_os("linux", "prctl");
110106

111-
let option = this.read_scalar(option)?.to_i32()?;
107+
if args.len() < 1 {
108+
throw_ub_format!(
109+
"incorrect number of arguments for `prctl`: got {}, expected at least 1",
110+
args.len()
111+
);
112+
}
113+
114+
let option = this.read_scalar(&args[0])?.to_i32()?;
112115
if option == this.eval_libc_i32("PR_SET_NAME")? {
113-
let address = this.read_pointer(arg2)?;
116+
if args.len() < 2 {
117+
throw_ub_format!(
118+
"incorrect number of arguments for `prctl` with `PR_SET_NAME`: got {}, expected at least 2",
119+
args.len()
120+
);
121+
}
122+
123+
let address = this.read_pointer(&args[1])?;
114124
let mut name = this.read_c_str(address)?.to_owned();
115125
// The name should be no more than 16 bytes, including the null
116126
// byte. Since `read_c_str` returns the string without the null
117127
// byte, we need to truncate to 15.
118128
name.truncate(15);
119129
this.set_active_thread_name(name);
120130
} else if option == this.eval_libc_i32("PR_GET_NAME")? {
121-
let address = this.read_pointer(arg2)?;
131+
if args.len() < 2 {
132+
throw_ub_format!(
133+
"incorrect number of arguments for `prctl` with `PR_SET_NAME`: got {}, expected at least 2",
134+
args.len()
135+
);
136+
}
137+
138+
let address = this.read_pointer(&args[1])?;
122139
let mut name = this.get_active_thread_name().to_vec();
123140
name.push(0u8);
124141
assert!(name.len() <= 16);

tests/compile-fail/fs/unix_open_missing_required_mode.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,5 @@ fn main() {
1212
fn test_file_open_missing_needed_mode() {
1313
let name = b"missing_arg.txt\0";
1414
let name_ptr = name.as_ptr().cast::<libc::c_char>();
15-
let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT) }; //~ ERROR Undefined Behavior: incorrect number of arguments for `open` with `O_CREAT`: got 2, expected 3
15+
let _fd = unsafe { libc::open(name_ptr, libc::O_CREAT) }; //~ ERROR Undefined Behavior: incorrect number of arguments for `open` with `O_CREAT`: got 2, expected at least 3
1616
}

tests/compile-fail/fs/unix_open_too_many_args.rs

-16
This file was deleted.

0 commit comments

Comments
 (0)