@@ -15,7 +15,6 @@ use rustc_middle::ty::{self, layout::LayoutOf};
15
15
use rustc_target:: abi:: { Align , Size } ;
16
16
17
17
use crate :: * ;
18
- use helpers:: check_arg_count;
19
18
use shims:: os_str:: os_str_to_bytes;
20
19
use shims:: time:: system_time_to_duration;
21
20
@@ -479,16 +478,16 @@ fn maybe_sync_file(
479
478
impl < ' mir , ' tcx : ' mir > EvalContextExt < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
480
479
pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
481
480
fn open ( & mut self , args : & [ OpTy < ' tcx , Tag > ] ) -> InterpResult < ' tcx , i32 > {
482
- if args. len ( ) < 2 || args . len ( ) > 3 {
481
+ if args. len ( ) < 2 {
483
482
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 " ,
485
484
args. len( )
486
485
) ;
487
486
}
488
487
489
488
let this = self . eval_context_mut ( ) ;
490
489
491
- let path_op = & args[ 0 ] ;
490
+ let path = this . read_pointer ( & args[ 0 ] ) ? ;
492
491
let flag = this. read_scalar ( & args[ 1 ] ) ?. to_i32 ( ) ?;
493
492
494
493
let mut options = OpenOptions :: new ( ) ;
@@ -541,7 +540,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
541
540
this. read_scalar ( arg) ?. to_u32 ( ) ?
542
541
} else {
543
542
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" ,
545
544
args. len( )
546
545
) ;
547
546
} ;
@@ -572,7 +571,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
572
571
throw_unsup_format ! ( "unsupported flags {:#x}" , flag & !mirror) ;
573
572
}
574
573
575
- let path = this. read_path_from_c_str ( this . read_pointer ( path_op ) ? ) ?;
574
+ let path = this. read_path_from_c_str ( path ) ?;
576
575
577
576
// Reject if isolation is enabled.
578
577
if let IsolatedOp :: Reject ( reject_with) = this. machine . isolated_op {
@@ -614,7 +613,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
614
613
// `FD_CLOEXEC` value without checking if the flag is set for the file because `std`
615
614
// always sets this flag when opening a file. However we still need to check that the
616
615
// file itself is open.
617
- let & [ _, _] = check_arg_count ( args) ?;
618
616
if this. machine . file_handler . handles . contains_key ( & fd) {
619
617
Ok ( this. eval_libc_i32 ( "FD_CLOEXEC" ) ?)
620
618
} else {
@@ -627,8 +625,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
627
625
// because exec() isn't supported. The F_DUPFD and F_DUPFD_CLOEXEC commands only
628
626
// differ in whether the FD_CLOEXEC flag is pre-set on the new file descriptor,
629
627
// 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 ( ) ?;
632
635
633
636
let fh = & mut this. machine . file_handler ;
634
637
@@ -646,7 +649,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
646
649
None => return this. handle_not_found ( ) ,
647
650
}
648
651
} else if this. tcx . sess . target . os == "macos" && cmd == this. eval_libc_i32 ( "F_FULLFSYNC" ) ? {
649
- let & [ _, _] = check_arg_count ( args) ?;
650
652
if let Some ( file_descriptor) = this. machine . file_handler . handles . get ( & fd) {
651
653
// FIXME: Support fullfsync for all FDs
652
654
let FileHandle { file, writable } = file_descriptor. as_file_handle ( ) ?;
@@ -919,15 +921,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
919
921
dirfd_op : & OpTy < ' tcx , Tag > , // Should be an `int`
920
922
pathname_op : & OpTy < ' tcx , Tag > , // Should be a `const char *`
921
923
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`
923
925
statxbuf_op : & OpTy < ' tcx , Tag > , // Should be a `struct statx *`
924
926
) -> InterpResult < ' tcx , i32 > {
925
927
let this = self . eval_context_mut ( ) ;
926
928
927
929
this. assert_target_os ( "linux" , "statx" ) ;
928
930
929
- let statxbuf_ptr = this. read_pointer ( statxbuf_op ) ?;
931
+ let dirfd = this. read_scalar ( dirfd_op ) ? . to_i32 ( ) ?;
930
932
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) ?;
931
936
932
937
// If the statxbuf or pathname pointers are null, the function fails with `EFAULT`.
933
938
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
953
958
954
959
let path = this. read_path_from_c_str ( pathname_ptr) ?. into_owned ( ) ;
955
960
// 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 ( ) ?;
957
961
let empty_path_flag = flags & this. eval_libc ( "AT_EMPTY_PATH" ) ?. to_i32 ( ) ? != 0 ;
958
- let dirfd = this. read_scalar ( dirfd_op) ?. to_i32 ( ) ?;
959
962
// We only support:
960
963
// * interpreting `path` as an absolute directory,
961
964
// * interpreting `path` as a path relative to `dirfd` when the latter is `AT_FDCWD`, or
0 commit comments