Commit 58eff8e8 authored by Danilo Krummrich's avatar Danilo Krummrich Committed by Miguel Ojeda
Browse files

rust: treewide: switch to the kernel `Vec` type



Now that we got the kernel `Vec` in place, convert all existing `Vec`
users to make use of it.

Reviewed-by: default avatarAlice Ryhl <aliceryhl@google.com>
Reviewed-by: default avatarBenno Lossin <benno.lossin@proton.me>
Reviewed-by: default avatarGary Guo <gary@garyguo.net>
Signed-off-by: default avatarDanilo Krummrich <dakr@kernel.org>
Link: https://lore.kernel.org/r/20241004154149.93856-20-dakr@kernel.org


[ Converted `kasan_test_rust.rs` too, as discussed. - Miguel ]
Signed-off-by: default avatarMiguel Ojeda <ojeda@kernel.org>
parent 93e60231
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -11,7 +11,7 @@
/// drop the vector, and touch it.
#[no_mangle]
pub extern "C" fn kasan_test_rust_uaf() -> u8 {
    let mut v: Vec<u8> = Vec::new();
    let mut v: KVec<u8> = KVec::new();
    for _ in 0..4096 {
        v.push(0x42, GFP_KERNEL).unwrap();
    }
+5 −7
Original line number Diff line number Diff line
@@ -2,8 +2,7 @@

//! String representations.

use crate::alloc::{flags::*, vec_ext::VecExt, AllocError};
use alloc::vec::Vec;
use crate::alloc::{flags::*, AllocError, KVec};
use core::fmt::{self, Write};
use core::ops::{self, Deref, DerefMut, Index};

@@ -791,7 +790,7 @@ fn write_str(&mut self, s: &str) -> fmt::Result {
/// assert_eq!(s.is_ok(), false);
/// ```
pub struct CString {
    buf: Vec<u8>,
    buf: KVec<u8>,
}

impl CString {
@@ -804,7 +803,7 @@ pub fn try_from_fmt(args: fmt::Arguments<'_>) -> Result<Self, Error> {
        let size = f.bytes_written();

        // Allocate a vector with the required number of bytes, and write to it.
        let mut buf = <Vec<_> as VecExt<_>>::with_capacity(size, GFP_KERNEL)?;
        let mut buf = KVec::with_capacity(size, GFP_KERNEL)?;
        // SAFETY: The buffer stored in `buf` is at least of size `size` and is valid for writes.
        let mut f = unsafe { Formatter::from_buffer(buf.as_mut_ptr(), size) };
        f.write_fmt(args)?;
@@ -851,10 +850,9 @@ impl<'a> TryFrom<&'a CStr> for CString {
    type Error = AllocError;

    fn try_from(cstr: &'a CStr) -> Result<CString, AllocError> {
        let mut buf = Vec::new();
        let mut buf = KVec::new();

        <Vec<_> as VecExt<_>>::extend_from_slice(&mut buf, cstr.as_bytes_with_nul(), GFP_KERNEL)
            .map_err(|_| AllocError)?;
        buf.extend_from_slice(cstr.as_bytes_with_nul(), GFP_KERNEL)?;

        // INVARIANT: The `CStr` and `CString` types have the same invariants for
        // the string data, and we copied it over without changes.
+1 −1
Original line number Diff line number Diff line
@@ -43,7 +43,7 @@
/// struct InnerDirectory {
///     /// The sum of the bytes used by all files.
///     bytes_used: u64,
///     _files: Vec<File>,
///     _files: KVec<File>,
/// }
///
/// struct Directory {
+1 −1
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ unsafe fn from_foreign(_: *const core::ffi::c_void) -> Self {}
/// # use kernel::types::ScopeGuard;
/// fn example3(arg: bool) -> Result {
///     let mut vec =
///         ScopeGuard::new_with_data(Vec::new(), |v| pr_info!("vec had {} elements\n", v.len()));
///         ScopeGuard::new_with_data(KVec::new(), |v| pr_info!("vec had {} elements\n", v.len()));
///
///     vec.push(10u8, GFP_KERNEL)?;
///     if arg {
+7 −10
Original line number Diff line number Diff line
@@ -11,7 +11,6 @@
    prelude::*,
    transmute::{AsBytes, FromBytes},
};
use alloc::vec::Vec;
use core::ffi::{c_ulong, c_void};
use core::mem::{size_of, MaybeUninit};

@@ -46,7 +45,6 @@
/// every byte in the region.
///
/// ```no_run
/// use alloc::vec::Vec;
/// use core::ffi::c_void;
/// use kernel::error::Result;
/// use kernel::uaccess::{UserPtr, UserSlice};
@@ -54,7 +52,7 @@
/// fn bytes_add_one(uptr: UserPtr, len: usize) -> Result<()> {
///     let (read, mut write) = UserSlice::new(uptr, len).reader_writer();
///
///     let mut buf = Vec::new();
///     let mut buf = KVec::new();
///     read.read_all(&mut buf, GFP_KERNEL)?;
///
///     for b in &mut buf {
@@ -69,7 +67,6 @@
/// Example illustrating a TOCTOU (time-of-check to time-of-use) bug.
///
/// ```no_run
/// use alloc::vec::Vec;
/// use core::ffi::c_void;
/// use kernel::error::{code::EINVAL, Result};
/// use kernel::uaccess::{UserPtr, UserSlice};
@@ -78,21 +75,21 @@
/// fn is_valid(uptr: UserPtr, len: usize) -> Result<bool> {
///     let read = UserSlice::new(uptr, len).reader();
///
///     let mut buf = Vec::new();
///     let mut buf = KVec::new();
///     read.read_all(&mut buf, GFP_KERNEL)?;
///
///     todo!()
/// }
///
/// /// Returns the bytes behind this user pointer if they are valid.
/// fn get_bytes_if_valid(uptr: UserPtr, len: usize) -> Result<Vec<u8>> {
/// fn get_bytes_if_valid(uptr: UserPtr, len: usize) -> Result<KVec<u8>> {
///     if !is_valid(uptr, len)? {
///         return Err(EINVAL);
///     }
///
///     let read = UserSlice::new(uptr, len).reader();
///
///     let mut buf = Vec::new();
///     let mut buf = KVec::new();
///     read.read_all(&mut buf, GFP_KERNEL)?;
///
///     // THIS IS A BUG! The bytes could have changed since we checked them.
@@ -130,7 +127,7 @@ pub fn new(ptr: UserPtr, length: usize) -> Self {
    /// Reads the entirety of the user slice, appending it to the end of the provided buffer.
    ///
    /// Fails with [`EFAULT`] if the read happens on a bad address.
    pub fn read_all(self, buf: &mut Vec<u8>, flags: Flags) -> Result {
    pub fn read_all(self, buf: &mut KVec<u8>, flags: Flags) -> Result {
        self.reader().read_all(buf, flags)
    }

@@ -291,9 +288,9 @@ pub fn read<T: FromBytes>(&mut self) -> Result<T> {
    /// Reads the entirety of the user slice, appending it to the end of the provided buffer.
    ///
    /// Fails with [`EFAULT`] if the read happens on a bad address.
    pub fn read_all(mut self, buf: &mut Vec<u8>, flags: Flags) -> Result {
    pub fn read_all(mut self, buf: &mut KVec<u8>, flags: Flags) -> Result {
        let len = self.length;
        VecExt::<u8>::reserve(buf, len, flags)?;
        buf.reserve(len, flags)?;

        // The call to `try_reserve` was successful, so the spare capacity is at least `len` bytes
        // long.
Loading