Skip to content

Commit c6a3e67

Browse files
committed
access_ok is no longer needed.
1 parent adddec4 commit c6a3e67

File tree

4 files changed

+11
-51
lines changed

4 files changed

+11
-51
lines changed

rust/helpers.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,6 @@ void rust_helper_BUG(void)
1010
BUG();
1111
}
1212

13-
int rust_helper_access_ok(const void __user *addr, unsigned long n)
14-
{
15-
return access_ok(addr, n);
16-
}
17-
1813
unsigned long rust_helper_copy_from_user(void *to, const void __user *from, unsigned long n)
1914
{
2015
return copy_from_user(to, from, n);

rust/kernel/file_operations.rs

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ unsafe extern "C" fn read_callback<T: FileOperations>(
100100
offset: *mut bindings::loff_t,
101101
) -> c_types::c_ssize_t {
102102
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();
104104
let f = &*((*file).private_data as *const T);
105105
// No `FMODE_UNSIGNED_OFFSET` support, so `offset` must be in [0, 2^63).
106106
// 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>(
118118
offset: *mut bindings::loff_t,
119119
) -> c_types::c_ssize_t {
120120
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();
122122
let f = &*((*file).private_data as *const T);
123123
// No `FMODE_UNSIGNED_OFFSET` support, so `offset` must be in [0, 2^63).
124124
// See discussion in https://github.com/fishinabarrel/linux-kernel-module-rust/pull/113
@@ -356,26 +356,12 @@ pub struct IoctlCommand {
356356

357357
impl IoctlCommand {
358358
/// 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;
378361

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 _) });
379365
Self {
380366
cmd,
381367
arg,
@@ -395,7 +381,7 @@ impl IoctlCommand {
395381
return T::pure(handler, file, self.cmd, self.arg);
396382
}
397383

398-
let data = self.user_slice.take().ok_or(Error::EFAULT)?;
384+
let data = self.user_slice.take().ok_or(Error::EINVAL)?;
399385
const READ_WRITE: u32 = bindings::_IOC_READ | bindings::_IOC_WRITE;
400386
match dir {
401387
bindings::_IOC_WRITE => T::write(handler, file, self.cmd, &mut data.reader()),

rust/kernel/sysctl.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,10 +106,7 @@ unsafe extern "C" fn proc_handler<T: SysctlStorage>(
106106
return 0;
107107
}
108108

109-
let data = match UserSlicePtr::new(buffer, *len) {
110-
Ok(ptr) => ptr,
111-
Err(e) => return e.to_kernel_errno(),
112-
};
109+
let data = UserSlicePtr::new(buffer, *len);
113110
let storage = &*((*ctl).data as *const T);
114111
let (bytes_processed, result) = if write != 0 {
115112
let data = match data.read_all() {

rust/kernel/user_ptr.rs

Lines changed: 2 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ use alloc::vec::Vec;
99
use core::mem::{size_of, MaybeUninit};
1010

1111
extern "C" {
12-
fn rust_helper_access_ok(addr: *const c_types::c_void, len: c_types::c_ulong)
13-
-> c_types::c_int;
14-
1512
fn rust_helper_copy_from_user(
1613
to: *mut c_types::c_void,
1714
from: *const c_types::c_void,
@@ -82,29 +79,14 @@ pub struct UserSlicePtr(*mut c_types::c_void, usize);
8279
impl UserSlicePtr {
8380
/// Constructs a user slice from a raw pointer and a length in bytes.
8481
///
85-
/// Checks that the provided range is within the legal area for
86-
/// userspace memory, using `access_ok` (e.g., on i386, the range
87-
/// must be within the first 3 GiB), but does not check that
88-
/// the actual pages are mapped in the current process with
89-
/// appropriate permissions. Those checks are handled in the read
90-
/// and write methods.
91-
///
9282
/// # Safety
9383
///
94-
/// This is `unsafe` because if it is called within `set_fs(KERNEL_DS)`
95-
/// context then `access_ok` will not do anything. As a result the only
96-
/// place you can safely use this is with a `__user` pointer that was
97-
/// provided by the kernel.
98-
///
9984
/// Callers must also be careful to avoid time-of-check-time-of-use
10085
/// (TOCTOU) issues. The simplest way is to create a single instance of
10186
/// [`UserSlicePtr`] per user memory block as it reads each byte at
10287
/// most once.
103-
pub unsafe fn new(ptr: *mut c_types::c_void, length: usize) -> KernelResult<UserSlicePtr> {
104-
if rust_helper_access_ok(ptr, length as c_types::c_ulong) == 0 {
105-
return Err(error::Error::EFAULT);
106-
}
107-
Ok(UserSlicePtr(ptr, length))
88+
pub unsafe fn new(ptr: *mut c_types::c_void, length: usize) -> Self {
89+
UserSlicePtr(ptr, length)
10890
}
10991

11092
/// Reads the entirety of the user slice.

0 commit comments

Comments
 (0)