All of lore.kernel.org
 help / color / mirror / Atom feed
From: Boqun Feng <boqun.feng@gmail.com>
To: Alice Ryhl <aliceryhl@google.com>
Cc: "Miguel Ojeda" <ojeda@kernel.org>,
	"Matthew Wilcox" <willy@infradead.org>,
	"Lorenzo Stoakes" <lorenzo.stoakes@oracle.com>,
	"Vlastimil Babka" <vbabka@suse.cz>,
	"John Hubbard" <jhubbard@nvidia.com>,
	"Liam R. Howlett" <Liam.Howlett@oracle.com>,
	"Andrew Morton" <akpm@linux-foundation.org>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Arnd Bergmann" <arnd@arndb.de>,
	"Christian Brauner" <brauner@kernel.org>,
	"Jann Horn" <jannh@google.com>,
	"Suren Baghdasaryan" <surenb@google.com>,
	"Alex Gaynor" <alex.gaynor@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@kernel.org>,
	"Trevor Gross" <tmgross@umich.edu>,
	linux-kernel@vger.kernel.org, linux-mm@kvack.org,
	rust-for-linux@vger.kernel.org
Subject: Re: [PATCH v11 8/8] task: rust: rework how current is accessed
Date: Tue, 14 Jan 2025 07:30:30 -0800	[thread overview]
Message-ID: <Z4aDFk_BcSt5RZtO@boqun-archlinux> (raw)
In-Reply-To: <CAH5fLgg=+Y=v=X50VdaCWwRRRUpKzGvBB-ND+4LHx9CNeThVDg@mail.gmail.com>

On Mon, Jan 13, 2025 at 11:30:05AM +0100, Alice Ryhl wrote:
> On Tue, Dec 17, 2024 at 12:40 AM Boqun Feng <boqun.feng@gmail.com> wrote:
> >
> > On Wed, Dec 11, 2024 at 10:37:12AM +0000, Alice Ryhl wrote:
> > > Introduce a new type called `CurrentTask` that lets you perform various
> > > operations that are only safe on the `current` task. Use the new type to
> > > provide a way to access the current mm without incrementing its
> > > refcount.
> > >
> > > With this change, you can write stuff such as
> > >
> > >       let vma = current!().mm().lock_vma_under_rcu(addr);
> > >
> > > without incrementing any refcounts.
> > >
> > > This replaces the existing abstractions for accessing the current pid
> > > namespace. With the old approach, every field access to current involves
> > > both a macro and a unsafe helper function. The new approach simplifies
> > > that to a single safe function on the `CurrentTask` type. This makes it
> > > less heavy-weight to add additional current accessors in the future.
> > >
> > > That said, creating a `CurrentTask` type like the one in this patch
> > > requires that we are careful to ensure that it cannot escape the current
> > > task or otherwise access things after they are freed. To do this, I
> > > declared that it cannot escape the current "task context" where I
> > > defined a "task context" as essentially the region in which `current`
> > > remains unchanged. So e.g., release_task() or begin_new_exec() would
> > > leave the task context.
> > >
> > > If a userspace thread returns to userspace and later makes another
> > > syscall, then I consider the two syscalls to be different task contexts.
> > > This allows values stored in that task to be modified between syscalls,
> > > even if they're guaranteed to be immutable during a syscall.
> > >
> > > Ensuring correctness of `CurrentTask` is slightly tricky if we also want
> > > the ability to have a safe `kthread_use_mm()` implementation in Rust. To
> > > support that safely, there are two patterns we need to ensure are safe:
> > >
> > >       // Case 1: current!() called inside the scope.
> > >       let mm;
> > >       kthread_use_mm(some_mm, || {
> > >           mm = current!().mm();
> > >       });
> > >       drop(some_mm);
> > >       mm.do_something(); // UAF
> > >
> > > and:
> > >
> > >       // Case 2: current!() called before the scope.
> > >       let mm;
> > >       let task = current!();
> > >       kthread_use_mm(some_mm, || {
> > >           mm = task.mm();
> > >       });
> > >       drop(some_mm);
> > >       mm.do_something(); // UAF
> > >
> > > The existing `current!()` abstraction already natively prevents the
> > > first case: The `&CurrentTask` would be tied to the inner scope, so the
> > > borrow-checker ensures that no reference derived from it can escape the
> > > scope.
> > >
> > > Fixing the second case is a bit more tricky. The solution is to
> > > essentially pretend that the contents of the scope execute on an
> > > different thread, which means that only thread-safe types can cross the
> > > boundary. Since `CurrentTask` is marked `NotThreadSafe`, attempts to
> > > move it to another thread will fail, and this includes our fake pretend
> > > thread boundary.
> > >
> > > This has the disadvantage that other types that aren't thread-safe for
> > > reasons unrelated to `current` also cannot be moved across the
> > > `kthread_use_mm()` boundary. I consider this an acceptable tradeoff.
> > >
> > > Cc: Christian Brauner <brauner@kernel.org>
> > > Signed-off-by: Alice Ryhl <aliceryhl@google.com>
> > > ---
> > >  rust/kernel/mm.rs   |  22 ----
> > >  rust/kernel/task.rs | 284 ++++++++++++++++++++++++++++++----------------------
> > >  2 files changed, 167 insertions(+), 139 deletions(-)
> > >
> > > diff --git a/rust/kernel/mm.rs b/rust/kernel/mm.rs
> > > index 50f4861ae4b9..f7d1079391ef 100644
> > > --- a/rust/kernel/mm.rs
> > > +++ b/rust/kernel/mm.rs
> > > @@ -142,28 +142,6 @@ fn deref(&self) -> &MmWithUser {
> > >
> > >  // These methods are safe to call even if `mm_users` is zero.
> > >  impl Mm {
> > > -    /// Call `mmgrab` on `current.mm`.
> > > -    #[inline]
> > > -    pub fn mmgrab_current() -> Option<ARef<Mm>> {
> > > -        // SAFETY: It's safe to get the `mm` field from current.
> > > -        let mm = unsafe {
> > > -            let current = bindings::get_current();
> > > -            (*current).mm
> > > -        };
> > > -
> > > -        if mm.is_null() {
> > > -            return None;
> > > -        }
> > > -
> > > -        // SAFETY: The value of `current->mm` is guaranteed to be null or a valid `mm_struct`. We
> > > -        // just checked that it's not null. Furthermore, the returned `&Mm` is valid only for the
> > > -        // duration of this function, and `current->mm` will stay valid for that long.
> > > -        let mm = unsafe { Mm::from_raw(mm) };
> > > -
> > > -        // This increments the refcount using `mmgrab`.
> > > -        Some(ARef::from(mm))
> > > -    }
> > > -
> >
> > This is removed because of no user? If so, maybe don't introduce this at
> > all in the earlier patch of this series? The rest looks good to me.
> 
> I guess I can drop the temporary introduction of this. It's here due
> to the history of this series where originally it only had
> mmgrab_current, and Binder would use that. But with this patch, you

As someone who usually dig a lot of history in git, I would like to see
the drop of the temporary introduction ;-) If you're going to rebase,
please see whether the drop can be done easily, thanks! Not a block
issue though.

With or without the change, feel free to add:

Reviewed-by: Boqun Feng <boqun.feng@gmail.com>

Regards,
Boqun

> can use CurrentTask::mm() + ARef::from() to do the same thing. For
> Binder, the difference doesn't matter, but the latter is more powerful
> as you can access the current task's mm_struct without incrementing
> refcounts.
> 
> Alice

  reply	other threads:[~2025-01-14 15:31 UTC|newest]

Thread overview: 65+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <nGnC07PmUqofHiX7HfZAOCIK1-CPS7DF8kdGhDgJgPts5KYrCrimmovP-4YMVgI7WRmFnGwbdndTtxCfp278cg==@protonmail.internalid>
2024-12-11 10:37 ` [PATCH v11 0/8] Rust support for mm_struct, vm_area_struct, and mmap Alice Ryhl
2024-12-11 10:37   ` [PATCH v11 1/8] mm: rust: add abstraction for struct mm_struct Alice Ryhl
2024-12-16 11:31     ` Andreas Hindborg
2025-01-13  9:53       ` Alice Ryhl
2025-01-14 15:48         ` Lorenzo Stoakes
2025-01-15  1:54           ` John Hubbard
2025-01-15 12:13             ` Lorenzo Stoakes
2025-01-15 10:36         ` Andreas Hindborg
2025-01-15 20:20           ` John Hubbard
2025-01-17  0:45     ` Balbir Singh
2025-01-17 12:47       ` Alice Ryhl
2024-12-11 10:37   ` [PATCH v11 2/8] mm: rust: add vm_area_struct methods that require read access Alice Ryhl
2024-12-16 12:12     ` Andreas Hindborg
2025-01-08 12:21       ` Alice Ryhl
2025-01-09  8:02         ` Andreas Hindborg
2025-01-09  8:19           ` Lorenzo Stoakes
2025-01-09  9:50             ` Andreas Hindborg
2025-01-09 11:29               ` Lorenzo Stoakes
2025-01-09 15:32                 ` Andreas Hindborg
2025-01-13 14:45                   ` Lorenzo Stoakes
2025-01-14  9:50                     ` Alice Ryhl
2025-01-14 11:57                       ` Lorenzo Stoakes
2025-01-14 13:42                         ` Alice Ryhl
2025-01-14 15:33                           ` Lorenzo Stoakes
2025-01-15 11:02                         ` Andreas Hindborg
2025-01-15 11:04                           ` Alice Ryhl
2024-12-11 10:37   ` [PATCH v11 3/8] mm: rust: add vm_insert_page Alice Ryhl
2024-12-16 12:25     ` Andreas Hindborg
2025-01-13 10:02       ` Alice Ryhl
2025-01-15  9:33         ` Andreas Hindborg
2024-12-11 10:37   ` [PATCH v11 4/8] mm: rust: add lock_vma_under_rcu Alice Ryhl
2024-12-16 12:47     ` Andreas Hindborg
2025-01-13 10:04       ` Alice Ryhl
2025-01-15  9:34         ` Andreas Hindborg
2024-12-11 10:37   ` [PATCH v11 5/8] mm: rust: add mmput_async support Alice Ryhl
2024-12-16 13:10     ` Andreas Hindborg
2024-12-11 10:37   ` [PATCH v11 6/8] mm: rust: add VmAreaNew for f_ops->mmap() Alice Ryhl
2024-12-16 13:41     ` Andreas Hindborg
2025-01-08 12:23       ` Alice Ryhl
2025-01-09  8:19         ` Andreas Hindborg
2025-01-13 10:17           ` Alice Ryhl
2025-01-15  9:57             ` Andreas Hindborg
2024-12-17  9:31     ` Andreas Hindborg
2025-01-08 12:24       ` Alice Ryhl
2025-01-09  8:23         ` Andreas Hindborg
2025-01-13 10:18           ` Alice Ryhl
2025-01-10 13:34     ` Alice Ryhl
2025-01-10 16:09       ` Lorenzo Stoakes
2024-12-11 10:37   ` [PATCH v11 7/8] rust: miscdevice: add mmap support Alice Ryhl
2024-12-16 13:53     ` Andreas Hindborg
2024-12-11 10:37   ` [PATCH v11 8/8] task: rust: rework how current is accessed Alice Ryhl
2024-12-16 14:47     ` Andreas Hindborg
2025-01-08 12:32       ` Alice Ryhl
2025-01-09  8:42         ` Andreas Hindborg
2025-01-13 10:26           ` Alice Ryhl
2025-01-15 10:24             ` Andreas Hindborg
2024-12-16 23:40     ` Boqun Feng
2025-01-13 10:30       ` Alice Ryhl
2025-01-14 15:30         ` Boqun Feng [this message]
2024-12-11 10:47   ` [PATCH v11 0/8] Rust support for mm_struct, vm_area_struct, and mmap Alice Ryhl
2024-12-12 14:47     ` Konstantin Ryabitsev
2024-12-13 14:42       ` Alice Ryhl
2024-12-13 14:47         ` Konstantin Ryabitsev
2024-12-16 11:04   ` Andreas Hindborg
2024-12-16 11:46     ` Alice Ryhl

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=Z4aDFk_BcSt5RZtO@boqun-archlinux \
    --to=boqun.feng@gmail.com \
    --cc=Liam.Howlett@oracle.com \
    --cc=a.hindborg@kernel.org \
    --cc=akpm@linux-foundation.org \
    --cc=alex.gaynor@gmail.com \
    --cc=aliceryhl@google.com \
    --cc=arnd@arndb.de \
    --cc=benno.lossin@proton.me \
    --cc=bjorn3_gh@protonmail.com \
    --cc=brauner@kernel.org \
    --cc=gary@garyguo.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=jannh@google.com \
    --cc=jhubbard@nvidia.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=lorenzo.stoakes@oracle.com \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=surenb@google.com \
    --cc=tmgross@umich.edu \
    --cc=vbabka@suse.cz \
    --cc=willy@infradead.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.