Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.17.
  1// SPDX-License-Identifier: GPL-2.0
  2
  3//! Slices to user space memory regions.
  4//!
  5//! C header: [`include/linux/uaccess.h`](srctree/include/linux/uaccess.h)
  6
  7use crate::{
  8    alloc::Flags,
  9    bindings,
 10    error::Result,
 11    ffi::c_void,
 12    prelude::*,
 13    transmute::{AsBytes, FromBytes},
 14};
 15use core::mem::{size_of, MaybeUninit};
 16
 17/// The type used for userspace addresses.
 18pub type UserPtr = usize;
 19
 20/// A pointer to an area in userspace memory, which can be either read-only or read-write.
 21///
 22/// All methods on this struct are safe: attempting to read or write on bad addresses (either out of
 23/// the bound of the slice or unmapped addresses) will return [`EFAULT`]. Concurrent access,
 24/// *including data races to/from userspace memory*, is permitted, because fundamentally another
 25/// userspace thread/process could always be modifying memory at the same time (in the same way that
 26/// userspace Rust's [`std::io`] permits data races with the contents of files on disk). In the
 27/// presence of a race, the exact byte values read/written are unspecified but the operation is
 28/// well-defined. Kernelspace code should validate its copy of data after completing a read, and not
 29/// expect that multiple reads of the same address will return the same value.
 30///
 31/// These APIs are designed to make it difficult to accidentally write TOCTOU (time-of-check to
 32/// time-of-use) bugs. Every time a memory location is read, the reader's position is advanced by
 33/// the read length and the next read will start from there. This helps prevent accidentally reading
 34/// the same location twice and causing a TOCTOU bug.
 35///
 36/// Creating a [`UserSliceReader`] and/or [`UserSliceWriter`] consumes the `UserSlice`, helping
 37/// ensure that there aren't multiple readers or writers to the same location.
 38///
 39/// If double-fetching a memory location is necessary for some reason, then that is done by creating
 40/// multiple readers to the same memory location, e.g. using [`clone_reader`].
 41///
 42/// # Examples
 43///
 44/// Takes a region of userspace memory from the current process, and modify it by adding one to
 45/// every byte in the region.
 46///
 47/// ```no_run
 48/// use kernel::ffi::c_void;
 49/// use kernel::error::Result;
 50/// use kernel::uaccess::{UserPtr, UserSlice};
 51///
 52/// fn bytes_add_one(uptr: UserPtr, len: usize) -> Result<()> {
 53///     let (read, mut write) = UserSlice::new(uptr, len).reader_writer();
 54///
 55///     let mut buf = KVec::new();
 56///     read.read_all(&mut buf, GFP_KERNEL)?;
 57///
 58///     for b in &mut buf {
 59///         *b = b.wrapping_add(1);
 60///     }
 61///
 62///     write.write_slice(&buf)?;
 63///     Ok(())
 64/// }
 65/// ```
 66///
 67/// Example illustrating a TOCTOU (time-of-check to time-of-use) bug.
 68///
 69/// ```no_run
 70/// use kernel::ffi::c_void;
 71/// use kernel::error::{code::EINVAL, Result};
 72/// use kernel::uaccess::{UserPtr, UserSlice};
 73///
 74/// /// Returns whether the data in this region is valid.
 75/// fn is_valid(uptr: UserPtr, len: usize) -> Result<bool> {
 76///     let read = UserSlice::new(uptr, len).reader();
 77///
 78///     let mut buf = KVec::new();
 79///     read.read_all(&mut buf, GFP_KERNEL)?;
 80///
 81///     todo!()
 82/// }
 83///
 84/// /// Returns the bytes behind this user pointer if they are valid.
 85/// fn get_bytes_if_valid(uptr: UserPtr, len: usize) -> Result<KVec<u8>> {
 86///     if !is_valid(uptr, len)? {
 87///         return Err(EINVAL);
 88///     }
 89///
 90///     let read = UserSlice::new(uptr, len).reader();
 91///
 92///     let mut buf = KVec::new();
 93///     read.read_all(&mut buf, GFP_KERNEL)?;
 94///
 95///     // THIS IS A BUG! The bytes could have changed since we checked them.
 96///     //
 97///     // To avoid this kind of bug, don't call `UserSlice::new` multiple
 98///     // times with the same address.
 99///     Ok(buf)
100/// }
101/// ```
102///
103/// [`std::io`]: https://doc.rust-lang.org/std/io/index.html
104/// [`clone_reader`]: UserSliceReader::clone_reader
105pub struct UserSlice {
106    ptr: UserPtr,
107    length: usize,
108}
109
110impl UserSlice {
111    /// Constructs a user slice from a raw pointer and a length in bytes.
112    ///
113    /// Constructing a [`UserSlice`] performs no checks on the provided address and length, it can
114    /// safely be constructed inside a kernel thread with no current userspace process. Reads and
115    /// writes wrap the kernel APIs `copy_from_user` and `copy_to_user`, which check the memory map
116    /// of the current process and enforce that the address range is within the user range (no
117    /// additional calls to `access_ok` are needed). Validity of the pointer is checked when you
118    /// attempt to read or write, not in the call to `UserSlice::new`.
119    ///
120    /// Callers must be careful to avoid time-of-check-time-of-use (TOCTOU) issues. The simplest way
121    /// is to create a single instance of [`UserSlice`] per user memory block as it reads each byte
122    /// at most once.
123    pub fn new(ptr: UserPtr, length: usize) -> Self {
124        UserSlice { ptr, length }
125    }
126
127    /// Reads the entirety of the user slice, appending it to the end of the provided buffer.
128    ///
129    /// Fails with [`EFAULT`] if the read happens on a bad address.
130    pub fn read_all(self, buf: &mut KVec<u8>, flags: Flags) -> Result {
131        self.reader().read_all(buf, flags)
132    }
133
134    /// Constructs a [`UserSliceReader`].
135    pub fn reader(self) -> UserSliceReader {
136        UserSliceReader {
137            ptr: self.ptr,
138            length: self.length,
139        }
140    }
141
142    /// Constructs a [`UserSliceWriter`].
143    pub fn writer(self) -> UserSliceWriter {
144        UserSliceWriter {
145            ptr: self.ptr,
146            length: self.length,
147        }
148    }
149
150    /// Constructs both a [`UserSliceReader`] and a [`UserSliceWriter`].
151    ///
152    /// Usually when this is used, you will first read the data, and then overwrite it afterwards.
153    pub fn reader_writer(self) -> (UserSliceReader, UserSliceWriter) {
154        (
155            UserSliceReader {
156                ptr: self.ptr,
157                length: self.length,
158            },
159            UserSliceWriter {
160                ptr: self.ptr,
161                length: self.length,
162            },
163        )
164    }
165}
166
167/// A reader for [`UserSlice`].
168///
169/// Used to incrementally read from the user slice.
170pub struct UserSliceReader {
171    ptr: UserPtr,
172    length: usize,
173}
174
175impl UserSliceReader {
176    /// Skip the provided number of bytes.
177    ///
178    /// Returns an error if skipping more than the length of the buffer.
179    pub fn skip(&mut self, num_skip: usize) -> Result {
180        // Update `self.length` first since that's the fallible part of this operation.
181        self.length = self.length.checked_sub(num_skip).ok_or(EFAULT)?;
182        self.ptr = self.ptr.wrapping_add(num_skip);
183        Ok(())
184    }
185
186    /// Create a reader that can access the same range of data.
187    ///
188    /// Reading from the clone does not advance the current reader.
189    ///
190    /// The caller should take care to not introduce TOCTOU issues, as described in the
191    /// documentation for [`UserSlice`].
192    pub fn clone_reader(&self) -> UserSliceReader {
193        UserSliceReader {
194            ptr: self.ptr,
195            length: self.length,
196        }
197    }
198
199    /// Returns the number of bytes left to be read from this reader.
200    ///
201    /// Note that even reading less than this number of bytes may fail.
202    pub fn len(&self) -> usize {
203        self.length
204    }
205
206    /// Returns `true` if no data is available in the io buffer.
207    pub fn is_empty(&self) -> bool {
208        self.length == 0
209    }
210
211    /// Reads raw data from the user slice into a kernel buffer.
212    ///
213    /// For a version that uses `&mut [u8]`, please see [`UserSliceReader::read_slice`].
214    ///
215    /// Fails with [`EFAULT`] if the read happens on a bad address, or if the read goes out of
216    /// bounds of this [`UserSliceReader`]. This call may modify `out` even if it returns an error.
217    ///
218    /// # Guarantees
219    ///
220    /// After a successful call to this method, all bytes in `out` are initialized.
221    pub fn read_raw(&mut self, out: &mut [MaybeUninit<u8>]) -> Result {
222        let len = out.len();
223        let out_ptr = out.as_mut_ptr().cast::<c_void>();
224        if len > self.length {
225            return Err(EFAULT);
226        }
227        // SAFETY: `out_ptr` points into a mutable slice of length `len`, so we may write
228        // that many bytes to it.
229        let res = unsafe { bindings::copy_from_user(out_ptr, self.ptr as *const c_void, len) };
230        if res != 0 {
231            return Err(EFAULT);
232        }
233        self.ptr = self.ptr.wrapping_add(len);
234        self.length -= len;
235        Ok(())
236    }
237
238    /// Reads raw data from the user slice into a kernel buffer.
239    ///
240    /// Fails with [`EFAULT`] if the read happens on a bad address, or if the read goes out of
241    /// bounds of this [`UserSliceReader`]. This call may modify `out` even if it returns an error.
242    pub fn read_slice(&mut self, out: &mut [u8]) -> Result {
243        // SAFETY: The types are compatible and `read_raw` doesn't write uninitialized bytes to
244        // `out`.
245        let out = unsafe { &mut *(out as *mut [u8] as *mut [MaybeUninit<u8>]) };
246        self.read_raw(out)
247    }
248
249    /// Reads a value of the specified type.
250    ///
251    /// Fails with [`EFAULT`] if the read happens on a bad address, or if the read goes out of
252    /// bounds of this [`UserSliceReader`].
253    pub fn read<T: FromBytes>(&mut self) -> Result<T> {
254        let len = size_of::<T>();
255        if len > self.length {
256            return Err(EFAULT);
257        }
258        let mut out: MaybeUninit<T> = MaybeUninit::uninit();
259        // SAFETY: The local variable `out` is valid for writing `size_of::<T>()` bytes.
260        //
261        // By using the _copy_from_user variant, we skip the check_object_size check that verifies
262        // the kernel pointer. This mirrors the logic on the C side that skips the check when the
263        // length is a compile-time constant.
264        let res = unsafe {
265            bindings::_copy_from_user(
266                out.as_mut_ptr().cast::<c_void>(),
267                self.ptr as *const c_void,
268                len,
269            )
270        };
271        if res != 0 {
272            return Err(EFAULT);
273        }
274        self.ptr = self.ptr.wrapping_add(len);
275        self.length -= len;
276        // SAFETY: The read above has initialized all bytes in `out`, and since `T` implements
277        // `FromBytes`, any bit-pattern is a valid value for this type.
278        Ok(unsafe { out.assume_init() })
279    }
280
281    /// Reads the entirety of the user slice, appending it to the end of the provided buffer.
282    ///
283    /// Fails with [`EFAULT`] if the read happens on a bad address.
284    pub fn read_all(mut self, buf: &mut KVec<u8>, flags: Flags) -> Result {
285        let len = self.length;
286        buf.reserve(len, flags)?;
287
288        // The call to `try_reserve` was successful, so the spare capacity is at least `len` bytes
289        // long.
290        self.read_raw(&mut buf.spare_capacity_mut()[..len])?;
291
292        // SAFETY: Since the call to `read_raw` was successful, so the next `len` bytes of the
293        // vector have been initialized.
294        unsafe { buf.set_len(buf.len() + len) };
295        Ok(())
296    }
297}
298
299/// A writer for [`UserSlice`].
300///
301/// Used to incrementally write into the user slice.
302pub struct UserSliceWriter {
303    ptr: UserPtr,
304    length: usize,
305}
306
307impl UserSliceWriter {
308    /// Returns the amount of space remaining in this buffer.
309    ///
310    /// Note that even writing less than this number of bytes may fail.
311    pub fn len(&self) -> usize {
312        self.length
313    }
314
315    /// Returns `true` if no more data can be written to this buffer.
316    pub fn is_empty(&self) -> bool {
317        self.length == 0
318    }
319
320    /// Writes raw data to this user pointer from a kernel buffer.
321    ///
322    /// Fails with [`EFAULT`] if the write happens on a bad address, or if the write goes out of
323    /// bounds of this [`UserSliceWriter`]. This call may modify the associated userspace slice even
324    /// if it returns an error.
325    pub fn write_slice(&mut self, data: &[u8]) -> Result {
326        let len = data.len();
327        let data_ptr = data.as_ptr().cast::<c_void>();
328        if len > self.length {
329            return Err(EFAULT);
330        }
331        // SAFETY: `data_ptr` points into an immutable slice of length `len`, so we may read
332        // that many bytes from it.
333        let res = unsafe { bindings::copy_to_user(self.ptr as *mut c_void, data_ptr, len) };
334        if res != 0 {
335            return Err(EFAULT);
336        }
337        self.ptr = self.ptr.wrapping_add(len);
338        self.length -= len;
339        Ok(())
340    }
341
342    /// Writes the provided Rust value to this userspace pointer.
343    ///
344    /// Fails with [`EFAULT`] if the write happens on a bad address, or if the write goes out of
345    /// bounds of this [`UserSliceWriter`]. This call may modify the associated userspace slice even
346    /// if it returns an error.
347    pub fn write<T: AsBytes>(&mut self, value: &T) -> Result {
348        let len = size_of::<T>();
349        if len > self.length {
350            return Err(EFAULT);
351        }
352        // SAFETY: The reference points to a value of type `T`, so it is valid for reading
353        // `size_of::<T>()` bytes.
354        //
355        // By using the _copy_to_user variant, we skip the check_object_size check that verifies the
356        // kernel pointer. This mirrors the logic on the C side that skips the check when the length
357        // is a compile-time constant.
358        let res = unsafe {
359            bindings::_copy_to_user(
360                self.ptr as *mut c_void,
361                (value as *const T).cast::<c_void>(),
362                len,
363            )
364        };
365        if res != 0 {
366            return Err(EFAULT);
367        }
368        self.ptr = self.ptr.wrapping_add(len);
369        self.length -= len;
370        Ok(())
371    }
372}