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: Alice Ryhl <aliceryhl@google.com>
Reviewed-by: Benno Lossin <benno.lossin@proton.me>
Reviewed-by: Gary Guo <gary@garyguo.net>
Signed-off-by: Danilo 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: Miguel Ojeda <ojeda@kernel.org>
This commit is contained in:
Danilo Krummrich
2024-10-04 17:41:23 +02:00
committed by Miguel Ojeda
parent 93e602310f
commit 58eff8e872
7 changed files with 20 additions and 25 deletions

View File

@@ -11,7 +11,7 @@ use kernel::prelude::*;
/// drop the vector, and touch it. /// drop the vector, and touch it.
#[no_mangle] #[no_mangle]
pub extern "C" fn kasan_test_rust_uaf() -> u8 { 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 { for _ in 0..4096 {
v.push(0x42, GFP_KERNEL).unwrap(); v.push(0x42, GFP_KERNEL).unwrap();
} }

View File

@@ -2,8 +2,7 @@
//! String representations. //! String representations.
use crate::alloc::{flags::*, vec_ext::VecExt, AllocError}; use crate::alloc::{flags::*, AllocError, KVec};
use alloc::vec::Vec;
use core::fmt::{self, Write}; use core::fmt::{self, Write};
use core::ops::{self, Deref, DerefMut, Index}; use core::ops::{self, Deref, DerefMut, Index};
@@ -791,7 +790,7 @@ impl fmt::Write for Formatter {
/// assert_eq!(s.is_ok(), false); /// assert_eq!(s.is_ok(), false);
/// ``` /// ```
pub struct CString { pub struct CString {
buf: Vec<u8>, buf: KVec<u8>,
} }
impl CString { impl CString {
@@ -804,7 +803,7 @@ impl CString {
let size = f.bytes_written(); let size = f.bytes_written();
// Allocate a vector with the required number of bytes, and write to it. // 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. // 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) }; let mut f = unsafe { Formatter::from_buffer(buf.as_mut_ptr(), size) };
f.write_fmt(args)?; f.write_fmt(args)?;
@@ -851,10 +850,9 @@ impl<'a> TryFrom<&'a CStr> for CString {
type Error = AllocError; type Error = AllocError;
fn try_from(cstr: &'a CStr) -> Result<CString, 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) buf.extend_from_slice(cstr.as_bytes_with_nul(), GFP_KERNEL)?;
.map_err(|_| AllocError)?;
// INVARIANT: The `CStr` and `CString` types have the same invariants for // INVARIANT: The `CStr` and `CString` types have the same invariants for
// the string data, and we copied it over without changes. // the string data, and we copied it over without changes.

View File

@@ -43,7 +43,7 @@ use core::{cell::UnsafeCell, mem::size_of, ptr};
/// struct InnerDirectory { /// struct InnerDirectory {
/// /// The sum of the bytes used by all files. /// /// The sum of the bytes used by all files.
/// bytes_used: u64, /// bytes_used: u64,
/// _files: Vec<File>, /// _files: KVec<File>,
/// } /// }
/// ///
/// struct Directory { /// struct Directory {

View File

@@ -135,7 +135,7 @@ impl ForeignOwnable for () {
/// # use kernel::types::ScopeGuard; /// # use kernel::types::ScopeGuard;
/// fn example3(arg: bool) -> Result { /// fn example3(arg: bool) -> Result {
/// let mut vec = /// 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)?; /// vec.push(10u8, GFP_KERNEL)?;
/// if arg { /// if arg {

View File

@@ -11,7 +11,6 @@ use crate::{
prelude::*, prelude::*,
transmute::{AsBytes, FromBytes}, transmute::{AsBytes, FromBytes},
}; };
use alloc::vec::Vec;
use core::ffi::{c_ulong, c_void}; use core::ffi::{c_ulong, c_void};
use core::mem::{size_of, MaybeUninit}; use core::mem::{size_of, MaybeUninit};
@@ -46,7 +45,6 @@ pub type UserPtr = usize;
/// every byte in the region. /// every byte in the region.
/// ///
/// ```no_run /// ```no_run
/// use alloc::vec::Vec;
/// use core::ffi::c_void; /// use core::ffi::c_void;
/// use kernel::error::Result; /// use kernel::error::Result;
/// use kernel::uaccess::{UserPtr, UserSlice}; /// use kernel::uaccess::{UserPtr, UserSlice};
@@ -54,7 +52,7 @@ pub type UserPtr = usize;
/// fn bytes_add_one(uptr: UserPtr, len: usize) -> Result<()> { /// fn bytes_add_one(uptr: UserPtr, len: usize) -> Result<()> {
/// let (read, mut write) = UserSlice::new(uptr, len).reader_writer(); /// 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)?; /// read.read_all(&mut buf, GFP_KERNEL)?;
/// ///
/// for b in &mut buf { /// for b in &mut buf {
@@ -69,7 +67,6 @@ pub type UserPtr = usize;
/// Example illustrating a TOCTOU (time-of-check to time-of-use) bug. /// Example illustrating a TOCTOU (time-of-check to time-of-use) bug.
/// ///
/// ```no_run /// ```no_run
/// use alloc::vec::Vec;
/// use core::ffi::c_void; /// use core::ffi::c_void;
/// use kernel::error::{code::EINVAL, Result}; /// use kernel::error::{code::EINVAL, Result};
/// use kernel::uaccess::{UserPtr, UserSlice}; /// use kernel::uaccess::{UserPtr, UserSlice};
@@ -78,21 +75,21 @@ pub type UserPtr = usize;
/// fn is_valid(uptr: UserPtr, len: usize) -> Result<bool> { /// fn is_valid(uptr: UserPtr, len: usize) -> Result<bool> {
/// let read = UserSlice::new(uptr, len).reader(); /// let read = UserSlice::new(uptr, len).reader();
/// ///
/// let mut buf = Vec::new(); /// let mut buf = KVec::new();
/// read.read_all(&mut buf, GFP_KERNEL)?; /// read.read_all(&mut buf, GFP_KERNEL)?;
/// ///
/// todo!() /// todo!()
/// } /// }
/// ///
/// /// Returns the bytes behind this user pointer if they are valid. /// /// 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)? { /// if !is_valid(uptr, len)? {
/// return Err(EINVAL); /// return Err(EINVAL);
/// } /// }
/// ///
/// let read = UserSlice::new(uptr, len).reader(); /// let read = UserSlice::new(uptr, len).reader();
/// ///
/// let mut buf = Vec::new(); /// let mut buf = KVec::new();
/// read.read_all(&mut buf, GFP_KERNEL)?; /// read.read_all(&mut buf, GFP_KERNEL)?;
/// ///
/// // THIS IS A BUG! The bytes could have changed since we checked them. /// // THIS IS A BUG! The bytes could have changed since we checked them.
@@ -130,7 +127,7 @@ impl UserSlice {
/// Reads the entirety of the user slice, appending it to the end of the provided buffer. /// 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. /// 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) self.reader().read_all(buf, flags)
} }
@@ -291,9 +288,9 @@ impl UserSliceReader {
/// Reads the entirety of the user slice, appending it to the end of the provided buffer. /// 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. /// 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; 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 // The call to `try_reserve` was successful, so the spare capacity is at least `len` bytes
// long. // long.

View File

@@ -242,7 +242,7 @@ pub fn concat_idents(ts: TokenStream) -> TokenStream {
/// #[pin_data] /// #[pin_data]
/// struct DriverData { /// struct DriverData {
/// #[pin] /// #[pin]
/// queue: Mutex<Vec<Command>>, /// queue: Mutex<KVec<Command>>,
/// buf: KBox<[u8; 1024 * 1024]>, /// buf: KBox<[u8; 1024 * 1024]>,
/// } /// }
/// ``` /// ```
@@ -251,7 +251,7 @@ pub fn concat_idents(ts: TokenStream) -> TokenStream {
/// #[pin_data(PinnedDrop)] /// #[pin_data(PinnedDrop)]
/// struct DriverData { /// struct DriverData {
/// #[pin] /// #[pin]
/// queue: Mutex<Vec<Command>>, /// queue: Mutex<KVec<Command>>,
/// buf: KBox<[u8; 1024 * 1024]>, /// buf: KBox<[u8; 1024 * 1024]>,
/// raw_info: *mut Info, /// raw_info: *mut Info,
/// } /// }
@@ -281,7 +281,7 @@ pub fn pin_data(inner: TokenStream, item: TokenStream) -> TokenStream {
/// #[pin_data(PinnedDrop)] /// #[pin_data(PinnedDrop)]
/// struct DriverData { /// struct DriverData {
/// #[pin] /// #[pin]
/// queue: Mutex<Vec<Command>>, /// queue: Mutex<KVec<Command>>,
/// buf: KBox<[u8; 1024 * 1024]>, /// buf: KBox<[u8; 1024 * 1024]>,
/// raw_info: *mut Info, /// raw_info: *mut Info,
/// } /// }

View File

@@ -13,7 +13,7 @@ module! {
} }
struct RustMinimal { struct RustMinimal {
numbers: Vec<i32>, numbers: KVec<i32>,
} }
impl kernel::Module for RustMinimal { impl kernel::Module for RustMinimal {
@@ -21,7 +21,7 @@ impl kernel::Module for RustMinimal {
pr_info!("Rust minimal sample (init)\n"); pr_info!("Rust minimal sample (init)\n");
pr_info!("Am I built-in? {}\n", !cfg!(MODULE)); pr_info!("Am I built-in? {}\n", !cfg!(MODULE));
let mut numbers = Vec::new(); let mut numbers = KVec::new();
numbers.push(72, GFP_KERNEL)?; numbers.push(72, GFP_KERNEL)?;
numbers.push(108, GFP_KERNEL)?; numbers.push(108, GFP_KERNEL)?;
numbers.push(200, GFP_KERNEL)?; numbers.push(200, GFP_KERNEL)?;