[<prev] [next>] [day] [month] [year] [list]
Message-ID: <20240913112643.542914-3-benno.lossin@proton.me>
Date: Fri, 13 Sep 2024 11:27:01 +0000
From: Benno Lossin <benno.lossin@...ton.me>
To: Greg KH <gregkh@...uxfoundation.org>, Miguel Ojeda <ojeda@...nel.org>, Alex Gaynor <alex.gaynor@...il.com>, Wedson Almeida Filho <wedsonaf@...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@...sung.com>, Alice Ryhl <aliceryhl@...gle.com>, Trevor Gross <tmgross@...ch.edu>
Cc: rust-for-linux@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [RFC PATCH 2/3] WIP: rust: fs: mark data returned by inodes untrusted
This is only meant to show how one would use the untrusted data API, not
to be actually used in production, as I just added `Untrusted` where I
thought it might fit. I have no idea if this is actually the correct
place where the untrusted data path starts.
---
rust/kernel/fs/inode.rs | 33 +++++++++++++++++++++------------
1 file changed, 21 insertions(+), 12 deletions(-)
diff --git a/rust/kernel/fs/inode.rs b/rust/kernel/fs/inode.rs
index b2b7d000080e..349f7f1ab420 100644
--- a/rust/kernel/fs/inode.rs
+++ b/rust/kernel/fs/inode.rs
@@ -11,7 +11,9 @@
PageOffset, UnspecifiedFS,
};
use crate::error::{code::*, from_err_ptr, Result};
-use crate::types::{ARef, AlwaysRefCounted, Either, ForeignOwnable, Lockable, Locked, Opaque};
+use crate::types::{
+ ARef, AlwaysRefCounted, Either, ForeignOwnable, Lockable, Locked, Opaque, Untrusted,
+};
use crate::{
bindings, block, build_error, container_of, folio, folio::Folio, mem_cache::MemCache,
str::CStr, str::CString, time::Timespec,
@@ -133,21 +135,24 @@ pub unsafe fn mapper(&self) -> Mapper<T> {
pub unsafe fn mapped_folio(
&self,
offset: Offset,
- ) -> Result<folio::Mapped<'_, folio::PageCache<T>>> {
+ ) -> Result<Untrusted<folio::Mapped<'_, folio::PageCache<T>>>> {
let page_index = offset >> bindings::PAGE_SHIFT;
let page_offset = offset & ((bindings::PAGE_SIZE - 1) as Offset);
let folio = self.read_mapping_folio(page_index.try_into()?)?;
+ let folio = folio.into_inner_untrusted();
// SAFETY: The safety requirements guarantee that there are no concurrent mutable mappings
// of the folio.
- unsafe { Folio::map_owned(folio, page_offset.try_into()?) }
+ Ok(Untrusted::new_untrusted(unsafe {
+ Folio::map_owned(folio, page_offset.try_into()?)?
+ }))
}
/// Returns the folio at the given page index.
pub fn read_mapping_folio(
&self,
index: PageOffset,
- ) -> Result<ARef<Folio<folio::PageCache<T>>>> {
+ ) -> Result<Untrusted<ARef<Folio<folio::PageCache<T>>>>> {
let folio = from_err_ptr(unsafe {
bindings::read_mapping_folio(
(*self.0.get()).i_mapping,
@@ -159,7 +164,7 @@ pub fn read_mapping_folio(
.ok_or(EIO)?
.cast::<Folio<folio::PageCache<T>>>();
// SAFETY: The folio returned by read_mapping_folio has had its refcount incremented.
- Ok(unsafe { ARef::from_raw(ptr) })
+ Ok(Untrusted::new_untrusted(unsafe { ARef::from_raw(ptr) }))
}
/// Iterate over the given range, one folio at a time.
@@ -171,7 +176,7 @@ pub unsafe fn for_each_page<U>(
&self,
first: Offset,
len: Offset,
- mut cb: impl FnMut(&[u8]) -> Result<Option<U>>,
+ mut cb: impl FnMut(&Untrusted<[u8]>) -> Result<Option<U>>,
) -> Result<Option<U>> {
if first >= self.size() {
return Ok(None);
@@ -183,8 +188,9 @@ pub unsafe fn for_each_page<U>(
while remain > 0 {
// SAFETY: The safety requirements of this function satisfy those of `mapped_folio`.
let data = unsafe { self.mapped_folio(next)? };
+ let data = data.into_inner_untrusted();
let avail = cmp::min(data.len(), remain.try_into().unwrap_or(usize::MAX));
- let ret = cb(&data[..avail])?;
+ let ret = cb(Untrusted::new_untrusted_ref(&data[..avail]))?;
if ret.is_some() {
return Ok(ret);
}
@@ -297,7 +303,7 @@ impl<T: FileSystem + ?Sized, U: Deref<Target = INode<T>>> Locked<U, ReadSem> {
pub fn mapped_folio<'a>(
&'a self,
offset: Offset,
- ) -> Result<folio::Mapped<'a, folio::PageCache<T>>>
+ ) -> Result<Untrusted<folio::Mapped<'a, folio::PageCache<T>>>>
where
T: 'a,
{
@@ -315,7 +321,7 @@ pub fn for_each_page<V>(
&self,
first: Offset,
len: Offset,
- cb: impl FnMut(&[u8]) -> Result<Option<V>>,
+ cb: impl FnMut(&Untrusted<[u8]>) -> Result<Option<V>>,
) -> Result<Option<V>> {
if T::IS_UNSPECIFIED {
build_error!("unspecified file systems cannot safely map folios");
@@ -750,14 +756,17 @@ pub fn split_at(mut self, offset: Offset) -> (Self, Self) {
}
/// Returns a mapped folio at the given offset.
- pub fn mapped_folio(&self, offset: Offset) -> Result<folio::Mapped<'_, folio::PageCache<T>>> {
+ pub fn mapped_folio(
+ &self,
+ offset: Offset,
+ ) -> Result<Untrusted<folio::Mapped<'_, folio::PageCache<T>>>> {
if offset < self.begin || offset >= self.end {
return Err(ERANGE);
}
// SAFETY: By the type invariant, there are no other mutable mappings of the folio.
let mut map = unsafe { self.inode.mapped_folio(offset) }?;
- map.cap_len((self.end - offset).try_into()?);
+ map.untrusted_mut().cap_len((self.end - offset).try_into()?);
Ok(map)
}
@@ -766,7 +775,7 @@ pub fn for_each_page<U>(
&self,
first: Offset,
len: Offset,
- cb: impl FnMut(&[u8]) -> Result<Option<U>>,
+ cb: impl FnMut(&Untrusted<[u8]>) -> Result<Option<U>>,
) -> Result<Option<U>> {
if first < self.begin || first >= self.end {
return Err(ERANGE);
--
2.46.0
Powered by blists - more mailing lists