linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
From: Alice Ryhl <aliceryhl@google.com>
To: "Liam R. Howlett" <Liam.Howlett@oracle.com>,
	"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	"Carlos Llamas" <cmllamas@google.com>,
	"Jann Horn" <jannh@google.com>, "Miguel Ojeda" <ojeda@kernel.org>,
	"Boqun Feng" <boqun@kernel.org>, "Gary Guo" <gary@garyguo.net>,
	"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
	"Benno Lossin" <lossin@kernel.org>,
	"Andreas Hindborg" <a.hindborg@kernel.org>,
	"Trevor Gross" <tmgross@umich.edu>,
	"Danilo Krummrich" <dakr@kernel.org>,
	"Lorenzo Stoakes" <lorenzo.stoakes@oracle.com>,
	linux-kernel@vger.kernel.org, rust-for-linux@vger.kernel.org,
	linux-mm@kvack.org, stable@vger.kernel.org
Subject: Re: [PATCH v2 1/2] rust_binder: check ownership before using vma
Date: Wed, 18 Feb 2026 16:39:42 +0000	[thread overview]
Message-ID: <aZXrTlNHyW-HZs1C@google.com> (raw)
In-Reply-To: <n2nq4aypj6hgafy36z2527tyvetgcypcrn2v3hvs6dws2mtwnl@jiszbxj4mrog>

On Wed, Feb 18, 2026 at 10:54:46AM -0500, Liam R. Howlett wrote:
> * Alice Ryhl <aliceryhl@google.com> [260218 06:53]:
> > When installing missing pages (or zapping them), Rust Binder will look
> > up the vma in the mm by address, and then call vm_insert_page (or
> > zap_page_range_single). However, if the vma is closed and replaced with
> > a different vma at the same address, this can lead to Rust Binder
> > installing pages into the wrong vma.
> > 
> > By installing the page into a writable vma, it becomes possible to write
> > to your own binder pages, which are normally read-only. Although you're
> > not supposed to be able to write to those pages, the intent behind the
> > design of Rust Binder is that even if you get that ability, it should not
> > lead to anything bad. Unfortunately, due to another bug, that is not the
> > case.
> > 
> > To fix this, store a pointer in vm_private_data and check that the vma
> > returned by vma_lookup() has the right vm_ops and vm_private_data before
> > trying to use the vma. This should ensure that Rust Binder will refuse
> > to interact with any other VMA. The plan is to introduce more vma
> > abstractions to avoid this unsafe access to vm_ops and vm_private_data,
> > but for now let's start with the simplest possible fix.
> 
> You probably already know this, but there are a list of ways we can
> ensure the vma is stable, listed in Documentation/mm/process_addrs.rst.
> Check the "Lock usage" section.
> 
> I'd feel more comfortable using one of the described ways to maintain a
> stable vma instead of rolling your own here - we may break your way by
> accident, or it might cause issues with future changes.
> 
> When do you think we can move to one of the standard ways of ensuring
> the vma is stable?

If you're referring to the fact that the vma can't change while you hold
a lock, then that doesn't apply here because this is about finding the
vma again from an ioctl or shrinker callback, not keeping is stable
during a single function call scope.

It would be nice to get rid of all this special mm logic in Binder,
though. For the vm_insert_page() call from ioctls, we can replace it
with a vm_fault callback (pending perf analysis). I have no idea how to
get rid of the zap_page_range_single() in the shrinker, though.


To give a quick recap: The basic idea behind what Binder does is that it
maintains an array of nullable struct page pointers. Each page may be on
one of three states:

1. In use.
2. Not in use.
3. Completely missing. (Access is segfault.)

Accessing a page in state 2 or 3 isn't legal. Pages may alternate
between 1 and 2 in very quick succession, so for perf reasons we do not
free or unmap pages when they stop being in use. That happens only in
the shrinker callback, which is when pages are moved from 2 to 3 by
unmapping and freeing the page.

Binder explicitly calls vm_insert_page() to move from 3 to 1 (from ioctl
context), and explicitly calls zap_page_range_single() to move from 2 to 3
(from shrinker context). This way, the vma reflects Binder's internal
struct page array at all times.

Changing a Binder vma after creation is not really supported at all.

Note that vm_insert_page() is called from the ioctl context of a
*different* process than the one the vma is mapped in. That's because
it's called from the sender process, and the vma is mapped into the
receiver's address space.

> > C Binder performs the same check in a slightly different way: it
> > provides a vm_ops->close that sets a boolean to true, then checks that
> > boolean after calling vma_lookup(), but this is more fragile
> > than the solution in this patch. (We probably still want to do both, but
> > the vm_ops->close callback will be added later as part of the follow-up
> > vma API changes.)
> 
> If I understand this correctly, setting the boolean to true will close
> the loophole of replacing the vma with an exact duplicate (including
> private data and vm_ops) but with different write permissions.  I assume
> that is why we want both?

No, Binder clears VM_MAYWRITE in mmap so you can never create a writable
version of a Binder vma.

> > It's still possible to remap the vma so that pages appear in the right
> > vma, but at the wrong offset, but this is a separate issue and will be
> > fixed when Rust Binder gets a vm_ops->close callback.

The main thing a close callback would give you is ensuring the Binder fd
becomes unusable once you close the vma.

Alice


  reply	other threads:[~2026-02-18 16:39 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-18 11:53 [PATCH v2 0/2] Fix VMA confusion in Rust Binder Alice Ryhl
2026-02-18 11:53 ` [PATCH v2 1/2] rust_binder: check ownership before using vma Alice Ryhl
2026-02-18 13:47   ` Danilo Krummrich
2026-02-18 15:54   ` Liam R. Howlett
2026-02-18 16:39     ` Alice Ryhl [this message]
2026-02-18 11:53 ` [PATCH v2 2/2] rust_binder: avoid reading the written value in offsets array Alice Ryhl
2026-02-18 16:02   ` Liam R. Howlett

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=aZXrTlNHyW-HZs1C@google.com \
    --to=aliceryhl@google.com \
    --cc=Liam.Howlett@oracle.com \
    --cc=a.hindborg@kernel.org \
    --cc=bjorn3_gh@protonmail.com \
    --cc=boqun@kernel.org \
    --cc=cmllamas@google.com \
    --cc=dakr@kernel.org \
    --cc=gary@garyguo.net \
    --cc=gregkh@linuxfoundation.org \
    --cc=jannh@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mm@kvack.org \
    --cc=lorenzo.stoakes@oracle.com \
    --cc=lossin@kernel.org \
    --cc=ojeda@kernel.org \
    --cc=rust-for-linux@vger.kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=tmgross@umich.edu \
    /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