@@ -113,16 +113,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
113
113
114
114
// Dynamically invoked syscalls
115
115
"syscall" => {
116
- // FIXME: The libc syscall() function is a variadic function.
117
- // It's valid to call it with more arguments than a syscall
118
- // needs, so none of these syscalls should use check_arg_count.
119
- // It's even valid to call it with the wrong type of arguments,
120
- // as long as they'd end up in the same place with the calling
121
- // convention used. (E.g. using a `usize` instead of a pointer.)
122
- // It's not directly clear which number, size, and type of arguments
123
- // are acceptable in which cases and which aren't. (E.g. some
124
- // types might take up the space of two registers.)
125
- // So this needs to be researched first.
116
+ // The syscall variadic function is legal to call with more arguments than needed,
117
+ // extra arguments are simply ignored. However, all arguments need to be scalars;
118
+ // other types might be treated differently by the calling convention.
119
+ for arg in args {
120
+ if !matches ! ( arg. layout. abi, rustc_target:: abi:: Abi :: Scalar ( _) ) {
121
+ throw_ub_format ! ( "`syscall` arguments must all have scalar layout, but {} does not" , arg. layout. ty) ;
122
+ }
123
+ }
126
124
127
125
let sys_getrandom = this
128
126
. eval_libc ( "SYS_getrandom" ) ?
@@ -144,22 +142,26 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
144
142
// is called if a `HashMap` is created the regular way (e.g. HashMap<K, V>).
145
143
id if id == sys_getrandom => {
146
144
// The first argument is the syscall id, so skip over it.
147
- let & [ _, ptr, len, flags] = check_arg_count ( args) ?;
148
- getrandom ( this, ptr, len, flags, dest) ?;
145
+ if args. len ( ) < 4 {
146
+ throw_ub_format ! ( "incorrect number of arguments for `getrandom` syscall: got {}, expected at least 4" , args. len( ) ) ;
147
+ }
148
+ getrandom ( this, args[ 1 ] , args[ 2 ] , args[ 3 ] , dest) ?;
149
149
}
150
150
// `statx` is used by `libstd` to retrieve metadata information on `linux`
151
151
// instead of using `stat`,`lstat` or `fstat` as on `macos`.
152
152
id if id == sys_statx => {
153
153
// The first argument is the syscall id, so skip over it.
154
- let & [ _, dirfd, pathname, flags, mask, statxbuf] = check_arg_count ( args) ?;
155
- let result = this. linux_statx ( dirfd, pathname, flags, mask, statxbuf) ?;
154
+ if args. len ( ) < 6 {
155
+ throw_ub_format ! ( "incorrect number of arguments for `statx` syscall: got {}, expected at least 6" , args. len( ) ) ;
156
+ }
157
+ let result = this. linux_statx ( args[ 1 ] , args[ 2 ] , args[ 3 ] , args[ 4 ] , args[ 5 ] ) ?;
156
158
this. write_scalar ( Scalar :: from_machine_isize ( result. into ( ) , this) , dest) ?;
157
159
}
158
160
// `futex` is used by some synchonization primitives.
159
161
id if id == sys_futex => {
160
162
futex ( this, args, dest) ?;
161
163
}
162
- id => throw_unsup_format ! ( "miri does not support syscall ID {}" , id) ,
164
+ id => throw_unsup_format ! ( "Miri does not support syscall ID {}" , id) ,
163
165
}
164
166
}
165
167
0 commit comments