Skip to content

Commit

Permalink
treat prctl like a variadic function
Browse files Browse the repository at this point in the history
  • Loading branch information
RalfJung committed Apr 7, 2022
1 parent 59ee672 commit cac48dd
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 32 deletions.
2 changes: 1 addition & 1 deletion src/shims/posix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -921,7 +921,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
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();
Expand Down
6 changes: 3 additions & 3 deletions src/shims/posix/linux/foreign_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,9 +106,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx

// 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" => {
Expand Down
36 changes: 25 additions & 11 deletions src/shims/posix/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,28 +97,42 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, '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
// byte, we need to truncate to 15.
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);
Expand Down
2 changes: 1 addition & 1 deletion tests/compile-fail/fs/unix_open_missing_required_mode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<libc::c_char>();
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
}
16 changes: 0 additions & 16 deletions tests/compile-fail/fs/unix_open_too_many_args.rs

This file was deleted.

0 comments on commit cac48dd

Please sign in to comment.