@@ -100,7 +100,7 @@ unsafe extern "C" fn read_callback<T: FileOperations>(
100
100
offset : * mut bindings:: loff_t ,
101
101
) -> c_types:: c_ssize_t {
102
102
from_kernel_result ! {
103
- let mut data = UserSlicePtr :: new( buf as * mut c_types:: c_void, len) ? . writer( ) ;
103
+ let mut data = UserSlicePtr :: new( buf as * mut c_types:: c_void, len) . writer( ) ;
104
104
let f = & * ( ( * file) . private_data as * const T ) ;
105
105
// No `FMODE_UNSIGNED_OFFSET` support, so `offset` must be in [0, 2^63).
106
106
// See discussion in https://github.com/fishinabarrel/linux-kernel-module-rust/pull/113
@@ -118,7 +118,7 @@ unsafe extern "C" fn write_callback<T: FileOperations>(
118
118
offset : * mut bindings:: loff_t ,
119
119
) -> c_types:: c_ssize_t {
120
120
from_kernel_result ! {
121
- let mut data = UserSlicePtr :: new( buf as * mut c_types:: c_void, len) ? . reader( ) ;
121
+ let mut data = UserSlicePtr :: new( buf as * mut c_types:: c_void, len) . reader( ) ;
122
122
let f = & * ( ( * file) . private_data as * const T ) ;
123
123
// No `FMODE_UNSIGNED_OFFSET` support, so `offset` must be in [0, 2^63).
124
124
// See discussion in https://github.com/fishinabarrel/linux-kernel-module-rust/pull/113
@@ -356,26 +356,12 @@ pub struct IoctlCommand {
356
356
357
357
impl IoctlCommand {
358
358
/// Constructs a new [`IoctlCommand`].
359
- ///
360
- /// # Safety
361
- ///
362
- /// The caller must ensure that `fs` is compatible with `arg` and the original caller's
363
- /// context. For example, if the original caller is from userland (e.g., through the ioctl
364
- /// syscall), then `arg` is untrusted and `fs` should therefore be `USER_DS`.
365
- unsafe fn new ( cmd : u32 , arg : usize ) -> Self {
366
- let user_slice = {
367
- let dir = ( cmd >> bindings:: _IOC_DIRSHIFT) & bindings:: _IOC_DIRMASK;
368
- if dir == bindings:: _IOC_NONE {
369
- None
370
- } else {
371
- let size = ( cmd >> bindings:: _IOC_SIZESHIFT) & bindings:: _IOC_SIZEMASK;
372
-
373
- // SAFETY: We only create one instance of the user slice, so TOCTOU issues are not
374
- // possible. The `set_fs` requirements are imposed on the caller.
375
- UserSlicePtr :: new ( arg as _ , size as _ ) . ok ( )
376
- }
377
- } ;
359
+ fn new ( cmd : u32 , arg : usize ) -> Self {
360
+ let size = ( cmd >> bindings:: _IOC_SIZESHIFT) & bindings:: _IOC_SIZEMASK;
378
361
362
+ // SAFETY: We only create one instance of the user slice per ioctl call, so TOCTOU issues
363
+ // are not possible.
364
+ let user_slice = Some ( unsafe { UserSlicePtr :: new ( arg as _ , size as _ ) } ) ;
379
365
Self {
380
366
cmd,
381
367
arg,
@@ -395,7 +381,7 @@ impl IoctlCommand {
395
381
return T :: pure ( handler, file, self . cmd , self . arg ) ;
396
382
}
397
383
398
- let data = self . user_slice . take ( ) . ok_or ( Error :: EFAULT ) ?;
384
+ let data = self . user_slice . take ( ) . ok_or ( Error :: EINVAL ) ?;
399
385
const READ_WRITE : u32 = bindings:: _IOC_READ | bindings:: _IOC_WRITE;
400
386
match dir {
401
387
bindings:: _IOC_WRITE => T :: write ( handler, file, self . cmd , & mut data. reader ( ) ) ,
0 commit comments