rust-for-linux.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Benno Lossin <benno.lossin@proton.me>
To: "Greg KH" <gregkh@linuxfoundation.org>,
	"Miguel Ojeda" <ojeda@kernel.org>,
	"Alex Gaynor" <alex.gaynor@gmail.com>,
	"Wedson Almeida Filho" <wedsonaf@gmail.com>,
	"Boqun Feng" <boqun.feng@gmail.com>,
	"Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <benno.lossin@proton.me>,
	"Andreas Hindborg" <a.hindborg@samsung.com>,
	"Alice Ryhl" <aliceryhl@google.com>,
	"Trevor Gross" <tmgross@umich.edu>
Cc: rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [RFC PATCH 2/3] WIP: rust: fs: mark data returned by inodes untrusted
Date: Fri, 13 Sep 2024 11:27:01 +0000	[thread overview]
Message-ID: <20240913112643.542914-3-benno.lossin@proton.me> (raw)
In-Reply-To: <20240913112643.542914-1-benno.lossin@proton.me>

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



  parent reply	other threads:[~2024-09-13 11:27 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-13 11:26 [PATCH 0/3] Untrusted data abstraction Benno Lossin
2024-09-13 11:26 ` [PATCH 1/3] rust: add untrusted " Benno Lossin
2024-09-13 13:41   ` Finn Behrens
2024-09-13 13:47     ` Benno Lossin
2024-09-13 15:33   ` Simona Vetter
2024-09-13 16:49     ` Benno Lossin
2024-09-16 15:49       ` Simona Vetter
2024-09-18 15:40         ` Benno Lossin
2024-09-18 17:09           ` Greg KH
2024-09-18 17:33             ` Benno Lossin
2024-09-18 17:39               ` Greg KH
2024-09-20 14:29           ` Simona Vetter
2024-09-20 15:28             ` Benno Lossin
2024-09-21  7:45         ` Benno Lossin
2024-09-23 16:08           ` Simona Vetter
2024-09-23 16:56             ` Benno Lossin
2024-09-24  8:05               ` Simona Vetter
2024-09-13 11:27 ` Benno Lossin [this message]
2024-09-13 11:27 ` [RFC PATCH 3/3] WIP: rust: tarfs: use untrusted data API Benno Lossin
2024-09-13 12:10 ` [PATCH 0/3] Untrusted data abstraction Greg KH
2024-09-13 20:43 ` Simona Vetter
2024-09-13 21:31   ` Benno Lossin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240913112643.542914-3-benno.lossin@proton.me \
    --to=benno.lossin@proton.me \
    --cc=a.hindborg@samsung.com \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun.feng@gmail.com \
    --cc=gary@garyguo.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=tmgross@umich.edu \
    --cc=wedsonaf@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).