diff --git a/src/shims/posix/fs.rs b/src/shims/posix/fs.rs index 11b9082da64..5395d0f0bf1 100644 --- a/src/shims/posix/fs.rs +++ b/src/shims/posix/fs.rs @@ -921,7 +921,7 @@ fn linux_statx( dirfd_op: &OpTy<'tcx, Tag>, // Should be an `int` pathname_op: &OpTy<'tcx, Tag>, // Should be a `const char *` flags_op: &OpTy<'tcx, Tag>, // Should be an `int` - mask_op: &OpTy<'tcx, Tag>, // Should be an `unsigned int` + mask_op: &OpTy<'tcx, Tag>, // Should be an `unsigned int` statxbuf_op: &OpTy<'tcx, Tag>, // Should be a `struct statx *` ) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); diff --git a/src/shims/posix/linux/foreign_items.rs b/src/shims/posix/linux/foreign_items.rs index 453c77f1b53..339fb04dae3 100644 --- a/src/shims/posix/linux/foreign_items.rs +++ b/src/shims/posix/linux/foreign_items.rs @@ -106,9 +106,9 @@ fn emulate_foreign_item_by_name( // Threading "prctl" => { - let &[ref option, ref arg2, ref arg3, ref arg4, ref arg5] = - this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?; - let result = this.prctl(option, arg2, arg3, arg4, arg5)?; + // prctl is variadic. (It is not documented like that in the manpage, but defined like that in the libc crate.) + this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?; + let result = this.prctl(args)?; this.write_scalar(Scalar::from_i32(result), dest)?; } "pthread_condattr_setclock" => { diff --git a/src/shims/posix/thread.rs b/src/shims/posix/thread.rs index 58d48028f62..69875a9ffc4 100644 --- a/src/shims/posix/thread.rs +++ b/src/shims/posix/thread.rs @@ -97,20 +97,27 @@ fn pthread_self(&mut self, dest: &PlaceTy<'tcx, Tag>) -> InterpResult<'tcx> { this.write_scalar(Scalar::from_uint(thread_id.to_u32(), dest.layout.size), dest) } - fn prctl( - &mut self, - option: &OpTy<'tcx, Tag>, - arg2: &OpTy<'tcx, Tag>, - _arg3: &OpTy<'tcx, Tag>, - _arg4: &OpTy<'tcx, Tag>, - _arg5: &OpTy<'tcx, Tag>, - ) -> InterpResult<'tcx, i32> { + fn prctl(&mut self, args: &[OpTy<'tcx, Tag>]) -> InterpResult<'tcx, i32> { let this = self.eval_context_mut(); this.assert_target_os("linux", "prctl"); - let option = this.read_scalar(option)?.to_i32()?; + if args.len() < 1 { + throw_ub_format!( + "incorrect number of arguments for `prctl`: got {}, expected at least 1", + args.len() + ); + } + + let option = this.read_scalar(&args[0])?.to_i32()?; if option == this.eval_libc_i32("PR_SET_NAME")? { - let address = this.read_pointer(arg2)?; + if args.len() < 2 { + throw_ub_format!( + "incorrect number of arguments for `prctl` with `PR_SET_NAME`: got {}, expected at least 2", + args.len() + ); + } + + let address = this.read_pointer(&args[1])?; let mut name = this.read_c_str(address)?.to_owned(); // The name should be no more than 16 bytes, including the null // byte. Since `read_c_str` returns the string without the null @@ -118,7 +125,14 @@ fn prctl( name.truncate(15); this.set_active_thread_name(name); } else if option == this.eval_libc_i32("PR_GET_NAME")? { - let address = this.read_pointer(arg2)?; + if args.len() < 2 { + throw_ub_format!( + "incorrect number of arguments for `prctl` with `PR_SET_NAME`: got {}, expected at least 2", + args.len() + ); + } + + let address = this.read_pointer(&args[1])?; let mut name = this.get_active_thread_name().to_vec(); name.push(0u8); assert!(name.len() <= 16); diff --git a/tests/compile-fail/fs/unix_open_missing_required_mode.rs b/tests/compile-fail/fs/unix_open_missing_required_mode.rs index 2bac7291254..bd2ae6094be 100644 --- a/tests/compile-fail/fs/unix_open_missing_required_mode.rs +++ b/tests/compile-fail/fs/unix_open_missing_required_mode.rs @@ -12,5 +12,5 @@ fn main() { fn test_file_open_missing_needed_mode() { let name = b"missing_arg.txt\0"; let name_ptr = name.as_ptr().cast::(); - 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 + 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 } diff --git a/tests/compile-fail/fs/unix_open_too_many_args.rs b/tests/compile-fail/fs/unix_open_too_many_args.rs deleted file mode 100644 index 9df7415d313..00000000000 --- a/tests/compile-fail/fs/unix_open_too_many_args.rs +++ /dev/null @@ -1,16 +0,0 @@ -// ignore-windows: No libc on Windows -// compile-flags: -Zmiri-disable-isolation - -#![feature(rustc_private)] - -extern crate libc; - -fn main() { - test_open_too_many_args(); -} - -fn test_open_too_many_args() { - let name = b"too_many_args.txt\0"; - let name_ptr = name.as_ptr().cast::(); - let _fd = unsafe { libc::open(name_ptr, libc::O_RDONLY, 0, 0) }; //~ ERROR Undefined Behavior: incorrect number of arguments for `open`: got 4, expected 2 or 3 -}