@@ -15,7 +15,6 @@ use rustc_middle::ty::{self, layout::LayoutOf};
1515use rustc_target:: abi:: { Align , Size } ;
1616
1717use crate :: * ;
18- use helpers:: check_arg_count;
1918use shims:: os_str:: os_str_to_bytes;
2019use shims:: time:: system_time_to_duration;
2120
@@ -479,16 +478,16 @@ fn maybe_sync_file(
479478impl < ' mir , ' tcx : ' mir > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
480479pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
481480 fn open ( & mut self , args : & [ OpTy < ' tcx , Tag > ] ) -> InterpResult < ' tcx , i32 > {
482- if args. len ( ) < 2 || args . len ( ) > 3 {
481+ if args. len ( ) < 2 {
483482 throw_ub_format ! (
484- "incorrect number of arguments for `open`: got {}, expected 2 or 3 " ,
483+ "incorrect number of arguments for `open`: got {}, expected at least 2 " ,
485484 args. len( )
486485 ) ;
487486 }
488487
489488 let this = self . eval_context_mut ( ) ;
490489
491- let path_op = & args[ 0 ] ;
490+ let path = this . read_pointer ( & args[ 0 ] ) ? ;
492491 let flag = this. read_scalar ( & args[ 1 ] ) ?. to_i32 ( ) ?;
493492
494493 let mut options = OpenOptions :: new ( ) ;
@@ -541,7 +540,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
541540 this. read_scalar ( arg) ?. to_u32 ( ) ?
542541 } else {
543542 throw_ub_format ! (
544- "incorrect number of arguments for `open` with `O_CREAT`: got {}, expected 3" ,
543+ "incorrect number of arguments for `open` with `O_CREAT`: got {}, expected at least 3" ,
545544 args. len( )
546545 ) ;
547546 } ;
@@ -572,7 +571,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
572571 throw_unsup_format ! ( "unsupported flags {:#x}" , flag & !mirror) ;
573572 }
574573
575- let path = this. read_path_from_c_str ( this . read_pointer ( path_op ) ? ) ?;
574+ let path = this. read_path_from_c_str ( path ) ?;
576575
577576 // Reject if isolation is enabled.
578577 if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
@@ -614,7 +613,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
614613 // `FD_CLOEXEC` value without checking if the flag is set for the file because `std`
615614 // always sets this flag when opening a file. However we still need to check that the
616615 // file itself is open.
617- let & [ _, _] = check_arg_count ( args) ?;
618616 if this. machine . file_handler . handles . contains_key ( & fd) {
619617 Ok ( this. eval_libc_i32 ( "FD_CLOEXEC" ) ?)
620618 } else {
@@ -627,8 +625,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
627625 // because exec() isn't supported. The F_DUPFD and F_DUPFD_CLOEXEC commands only
628626 // differ in whether the FD_CLOEXEC flag is pre-set on the new file descriptor,
629627 // thus they can share the same implementation here.
630- let & [ _, _, ref start] = check_arg_count ( args) ?;
631- let start = this. read_scalar ( start) ?. to_i32 ( ) ?;
628+ if args. len ( ) < 3 {
629+ throw_ub_format ! (
630+ "incorrect number of arguments for fcntl with cmd=`F_DUPFD`/`F_DUPFD_CLOEXEC`: got {}, expected at least 3" ,
631+ args. len( )
632+ ) ;
633+ }
634+ let start = this. read_scalar ( & args[ 2 ] ) ?. to_i32 ( ) ?;
632635
633636 let fh = & mut this. machine . file_handler ;
634637
@@ -646,7 +649,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
646649 None => return this. handle_not_found ( ) ,
647650 }
648651 } else if this. tcx . sess . target . os == "macos" && cmd == this. eval_libc_i32 ( "F_FULLFSYNC" ) ? {
649- let & [ _, _] = check_arg_count ( args) ?;
650652 if let Some ( file_descriptor) = this. machine . file_handler . handles . get ( & fd) {
651653 // FIXME: Support fullfsync for all FDs
652654 let FileHandle { file, writable } = file_descriptor. as_file_handle ( ) ?;
@@ -919,15 +921,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
919921 dirfd_op : & OpTy < ' tcx , Tag > , // Should be an `int`
920922 pathname_op : & OpTy < ' tcx , Tag > , // Should be a `const char *`
921923 flags_op : & OpTy < ' tcx , Tag > , // Should be an `int`
922- _mask_op : & OpTy < ' tcx , Tag > , // Should be an `unsigned int`
924+ mask_op : & OpTy < ' tcx , Tag > , // Should be an `unsigned int`
923925 statxbuf_op : & OpTy < ' tcx , Tag > , // Should be a `struct statx *`
924926 ) -> InterpResult < ' tcx , i32 > {
925927 let this = self . eval_context_mut ( ) ;
926928
927929 this. assert_target_os ( "linux" , "statx" ) ;
928930
929- let statxbuf_ptr = this. read_pointer ( statxbuf_op ) ?;
931+ let dirfd = this. read_scalar ( dirfd_op ) ? . to_i32 ( ) ?;
930932 let pathname_ptr = this. read_pointer ( pathname_op) ?;
933+ let flags = this. read_scalar ( flags_op) ?. to_i32 ( ) ?;
934+ let _mask = this. read_scalar ( mask_op) ?. to_u32 ( ) ?;
935+ let statxbuf_ptr = this. read_pointer ( statxbuf_op) ?;
931936
932937 // If the statxbuf or pathname pointers are null, the function fails with `EFAULT`.
933938 if this. ptr_is_null ( statxbuf_ptr) ? || this. ptr_is_null ( pathname_ptr) ? {
@@ -953,9 +958,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
953958
954959 let path = this. read_path_from_c_str ( pathname_ptr) ?. into_owned ( ) ;
955960 // See <https://github.com/rust-lang/rust/pull/79196> for a discussion of argument sizes.
956- let flags = this. read_scalar ( flags_op) ?. to_i32 ( ) ?;
957961 let empty_path_flag = flags & this. eval_libc ( "AT_EMPTY_PATH" ) ?. to_i32 ( ) ? != 0 ;
958- let dirfd = this. read_scalar ( dirfd_op) ?. to_i32 ( ) ?;
959962 // We only support:
960963 // * interpreting `path` as an absolute directory,
961964 // * interpreting `path` as a path relative to `dirfd` when the latter is `AT_FDCWD`, or
0 commit comments