• Wedson Almeida Filho's avatar
    rust: uaccess: add userspace pointers · 1b580e7b
    Wedson Almeida Filho authored
    A pointer to an area in userspace memory, which can be either read-only
    or read-write.
    
    All methods on this struct are safe: attempting to read or write on bad
    addresses (either out of the bound of the slice or unmapped addresses)
    will return `EFAULT`. Concurrent access, *including data races to/from
    userspace memory*, is permitted, because fundamentally another userspace
    thread/process could always be modifying memory at the same time (in the
    same way that userspace Rust's `std::io` permits data races with the
    contents of files on disk). In the presence of a race, the exact byte
    values read/written are unspecified but the operation is well-defined.
    Kernelspace code should validate its copy of data after completing a
    read, and not expect that multiple reads of the same address will return
    the same value.
    
    These APIs are designed to make it difficult to accidentally write
    TOCTOU bugs. Every time you read from a memory location, the pointer is
    advanced by the length so that you cannot use that reader to read the
    same memory location twice. Preventing double-fetches avoids TOCTOU
    bugs. This is accomplished by taking `self` by value to prevent
    obtaining multiple readers on a given `UserSlice`, and the readers only
    permitting forward reads. If double-fetching a memory location is
    necessary for some reason, then that is done by creating multiple
    readers to the same memory location.
    
    Constructing a `UserSlice` performs no checks on the provided address
    and length, it can safely be constructed inside a kernel thread with no
    current userspace process. Reads and writes wrap the kernel APIs
    `copy_from_user` and `copy_to_user`, which check the memory map of the
    current process and enforce that the address range is within the user
    range (no additional calls to `access_ok` are needed).
    
    This code is based on something that was originally written by Wedson on
    the old rust branch. It was modified by Alice by removing the
    `IoBufferReader` and `IoBufferWriter` traits, and various other changes.
    Signed-off-by: default avatarWedson Almeida Filho <wedsonaf@gmail.com>
    Reviewed-by: default avatarBenno Lossin <benno.lossin@proton.me>
    Reviewed-by: default avatarTrevor Gross <tmgross@umich.edu>
    Reviewed-by: default avatarBoqun Feng <boqun.feng@gmail.com>
    Co-developed-by: default avatarAlice Ryhl <aliceryhl@google.com>
    Signed-off-by: default avatarAlice Ryhl <aliceryhl@google.com>
    Link: https://lore.kernel.org/r/20240528-alice-mm-v7-1-78222c31b8f4@google.com
    [ Wrapped docs to 100 and added a few intra-doc links. - Miguel ]
    Signed-off-by: default avatarMiguel Ojeda <ojeda@kernel.org>
    1b580e7b
helpers.c 5.6 KB