[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20250421134909.464405-5-benno.lossin@proton.me>
Date: Mon, 21 Apr 2025 13:50:01 +0000
From: Benno Lossin <benno.lossin@...ton.me>
To: Simona Vetter <simona.vetter@...ll.ch>, Greg Kroah-Hartman <gregkh@...uxfoundation.org>, Miguel Ojeda <ojeda@...nel.org>, Alex Gaynor <alex.gaynor@...il.com>, Boqun Feng <boqun.feng@...il.com>, Gary Guo <gary@...yguo.net>, Björn Roy Baron <bjorn3_gh@...tonmail.com>, Benno Lossin <benno.lossin@...ton.me>, Andreas Hindborg <a.hindborg@...nel.org>, Alice Ryhl <aliceryhl@...gle.com>, Trevor Gross <tmgross@...ch.edu>, Arnd Bergmann <arnd@...db.de>
Cc: rust-for-linux@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH v3 4/4] rust: iov: use untrusted data API
Signed-off-by: Benno Lossin <benno.lossin@...ton.me>
---
This patch depends on Alice's `struct iov_iter` patch series:
https://lore.kernel.org/all/20250311-iov-iter-v1-0-f6c9134ea824@google.com
---
rust/kernel/iov.rs | 25 +++++++++++++++++--------
samples/rust/rust_misc_device.rs | 5 +++--
2 files changed, 20 insertions(+), 10 deletions(-)
diff --git a/rust/kernel/iov.rs b/rust/kernel/iov.rs
index dc32c27c5c76..840c2aa82e41 100644
--- a/rust/kernel/iov.rs
+++ b/rust/kernel/iov.rs
@@ -11,7 +11,9 @@
alloc::{Allocator, Flags},
bindings,
prelude::*,
+ transmute::cast_slice_mut,
types::Opaque,
+ validate::Untrusted,
};
use core::{marker::PhantomData, mem::MaybeUninit, slice};
@@ -124,10 +126,10 @@ pub unsafe fn revert(&mut self, bytes: usize) {
///
/// Returns the number of bytes that have been copied.
#[inline]
- pub fn copy_from_iter(&mut self, out: &mut [u8]) -> usize {
- // SAFETY: We will not write uninitialized bytes to `out`.
- let out = unsafe { &mut *(out as *mut [u8] as *mut [MaybeUninit<u8>]) };
-
+ pub fn copy_from_iter(&mut self, out: &mut [Untrusted<u8>]) -> usize {
+ // CAST: The call to `copy_from_iter_raw` below only writes initialized values.
+ // SAFETY: `Untrusted<T>` and `MaybeUninit<T>` transparently wrap a `T`.
+ let out: &mut [MaybeUninit<Untrusted<u8>>] = unsafe { cast_slice_mut(out) };
self.copy_from_iter_raw(out).len()
}
@@ -137,7 +139,7 @@ pub fn copy_from_iter(&mut self, out: &mut [u8]) -> usize {
#[inline]
pub fn copy_from_iter_vec<A: Allocator>(
&mut self,
- out: &mut Vec<u8, A>,
+ out: &mut Vec<Untrusted<u8>, A>,
flags: Flags,
) -> Result<usize> {
out.reserve(self.len(), flags)?;
@@ -152,7 +154,10 @@ pub fn copy_from_iter_vec<A: Allocator>(
/// Returns the sub-slice of the output that has been initialized. If the returned slice is
/// shorter than the input buffer, then the entire IO vector has been read.
#[inline]
- pub fn copy_from_iter_raw(&mut self, out: &mut [MaybeUninit<u8>]) -> &mut [u8] {
+ pub fn copy_from_iter_raw(
+ &mut self,
+ out: &mut [MaybeUninit<Untrusted<u8>>],
+ ) -> &mut [Untrusted<u8>] {
// SAFETY: `out` is valid for `out.len()` bytes.
let len =
unsafe { bindings::_copy_from_iter(out.as_mut_ptr().cast(), out.len(), self.as_raw()) };
@@ -274,7 +279,7 @@ pub unsafe fn revert(&mut self, bytes: usize) {
/// Returns the number of bytes that were written. If this is shorter than the provided slice,
/// then no more bytes can be written.
#[inline]
- pub fn copy_to_iter(&mut self, input: &[u8]) -> usize {
+ pub fn copy_to_iter(&mut self, input: &[Untrusted<u8>]) -> usize {
// SAFETY: `input` is valid for `input.len()` bytes.
unsafe { bindings::_copy_to_iter(input.as_ptr().cast(), input.len(), self.as_raw()) }
}
@@ -286,7 +291,11 @@ pub fn copy_to_iter(&mut self, input: &[u8]) -> usize {
/// that the file will appear to contain `contents` even if takes multiple reads to read the
/// entire file.
#[inline]
- pub fn simple_read_from_buffer(&mut self, ppos: &mut i64, contents: &[u8]) -> Result<usize> {
+ pub fn simple_read_from_buffer(
+ &mut self,
+ ppos: &mut i64,
+ contents: &[Untrusted<u8>],
+ ) -> Result<usize> {
if *ppos < 0 {
return Err(EINVAL);
}
diff --git a/samples/rust/rust_misc_device.rs b/samples/rust/rust_misc_device.rs
index 6405713fc8ff..bd2ac2e8f13d 100644
--- a/samples/rust/rust_misc_device.rs
+++ b/samples/rust/rust_misc_device.rs
@@ -109,6 +109,7 @@
sync::Mutex,
types::ARef,
uaccess::{UserSlice, UserSliceReader, UserSliceWriter},
+ validate::Untrusted,
};
const RUST_MISC_DEV_HELLO: u32 = _IO('|' as u32, 0x80);
@@ -145,7 +146,7 @@ fn init(_module: &'static ThisModule) -> impl PinInit<Self, Error> {
struct Inner {
value: i32,
- buffer: KVec<u8>,
+ buffer: Untrusted<KVec<u8>>,
}
#[pin_data(PinnedDrop)]
@@ -169,7 +170,7 @@ fn open(_file: &File, misc: &MiscDeviceRegistration<Self>) -> Result<Pin<KBox<Se
RustMiscDevice {
inner <- new_mutex!(Inner {
value: 0_i32,
- buffer: kvec![],
+ buffer: Untrusted::new(kvec![]),
}),
dev: dev,
}
--
2.48.1
Powered by blists - more mailing lists