From: Alice Ryhl <aliceryhl@google.com>
To: phasta@kernel.org
Cc: sashiko-reviews@lists.linux.dev, linux-media@vger.kernel.org,
ojeda@kernel.org,
Boris Brezillon <boris.brezillon@collabora.com>
Subject: Re: [PATCH 3/4] rust: Add dma_fence abstractions
Date: Tue, 2 Jun 2026 11:44:27 +0000 [thread overview]
Message-ID: <ah7CGySkyE7mSM8a@google.com> (raw)
In-Reply-To: <16dff07d28fca94749f14e9c91e6f812f605d6e5.camel@mailbox.org>
On Tue, Jun 02, 2026 at 01:31:52PM +0200, Philipp Stanner wrote:
> On Mon, 2026-06-01 at 13:44 +0000, Alice Ryhl wrote:
> > On Mon, Jun 01, 2026 at 03:14:05PM +0200, Philipp Stanner wrote:
> > > +Cc Boris
> > >
> > > On Mon, 2026-06-01 at 14:55 +0200, Alice Ryhl wrote:
> > > > On Mon, Jun 1, 2026 at 2:34 PM Philipp Stanner <phasta@mailbox.org> wrote:
> > > > >
> > > > > On Mon, 2026-06-01 at 10:20 +0000, Alice Ryhl wrote:
> > > > > > On Sat, May 30, 2026 at 03:06:21PM +0000, sashiko-bot@kernel.org wrote:
> > > > > > > > +impl<F: Send + Sync, C: Send + Sync> DriverFence<F, C> {
> > > > > > > > + fn as_raw(&self) -> *mut bindings::dma_fence {
> > > > > > > > + // SAFETY: Valid because `self` is valid.
> > > > > > > > + let fence_data = unsafe { &mut *self.data.as_ptr() };
> > > > > > >
> > > > > > > [Severity: High]
> > > > > > > Does this create an exclusive mutable reference to actively shared memory?
> > > > > > >
> > > > > > > DriverFenceData can be accessed concurrently by other threads holding Fence
> > > > > > > references (for instance, when checking if the fence is signaled). Creating
> > > > > > > a mutable reference (&mut) in Rust asserts exclusive access and violates
> > > > > > > aliasing rules, which allows the compiler to make invalid optimization
> > > > > > > assumptions.
> > > > > > >
> > > > > > > Could this use an immutable reference &*self.data.as_ptr() instead?
> > > > > >
> > > > > > Yes, please use an immutable reference here.
> > > > > >
> > > > > > > > +
> > > > > > > > + fence_data.inner.inner.get()
> > > > > > > > + }
> > > > > > >
> > > > > > > [ ... ]
> > > > > > >
> > > > > > > > +impl<F: Send + Sync, C: Send + Sync> DriverFenceBorrow<F, C> {
> > > > > > > > + fn as_raw(&self) -> *mut bindings::dma_fence {
> > > > > > > > + // SAFETY: Valid because `self` is valid.
> > > > > > > > + let fence_data = unsafe { &mut *self.data.as_ptr() };
> > > > > > >
> > > > > > > [Severity: High]
> > > > > > > Similar to DriverFence::as_raw(), does this also incorrectly create a
> > > > > > > mutable reference to shared data?
> > > > > >
> > > > > > Here as well.
> > > > >
> > > > > `data` is not shared. By design there is only ever one DriverFence, and
> > > > > the driver's data (`data.data`) is `Sync`.
> > > > >
> > > > > But I guess an immutable one should do the trick, too.
> > > >
> > > > There's only one DriverFence, but I can perform shared access to that
> > > > one DriverFence from two threads in parallel. You made the type Sync,
> > > > and this is what you are allowing when you do so.
> > >
> > > Nope, DriverFence is just Send, not Sync.
> > >
> > > data.data is Sync, but `data` in the code above is not the actual user
> > > data, but the memory backing it up.
> >
> > Ok, well, it probably should be Sync. I don't see any &self methods that
> > can't be called from multiple threads in parallel.
>
> No. Why?
>
> There can only be one owner of DriverFence.
Values normally have only one owner, and they are also normally Sync.
> Regarding the backend_ops that might access DriverFence::data, we take
> care to guard that.
>
> And DriverFence itself can only be owned by one party. That can only be
> accessed by many threads if the driver stuffs that fence into something
> that implements Sync.
If you don't implement Sync, then DriverFence cannot be stored in an
Arc. I wouldn't take away that ability unless you have to, and I don't
see anything in the DriverFence API that would mean you can't do that.
> > > > so even though
> > > > the fence context may be valid for another grace period, the *pointer*
> > > > to the fence context is not. The pointer could have been zeroed by the
> > > > destructor.
> > >
> > > That particular pointer to the DriverFenceData could have been zeroed.
> > > But potential other accessors have already crafted themselves a new
> > > pointer to the, by the power of RCU, still valid data. That new pointer
> > > is container-of-ed from struct dma_fence *f.
> >
> > I'm not talking about the pointer to DriverFenceData, I'm talking about
> > the pointer to the FenceCtx, or the pointer to the data (if F is
> > RcuBox).
>
> Yeah, but the backing memory is still alive. And new pointers to that
> memory get crafted by the accessors. If a callback accesses the data
> through `container_of(Fence)`, it gets a new pointer.
>
> So what's the problem?
>
> Where is the invalid pointer that someone is accessing?
>
> >
> > The Arc type is not a type that opts-out of &mut == exclusive, so the
> > second drop_in_place() above is assumed exclusive access to the
> > Arc<FenceCtx<F,C>> field.
>
> OK, so I think I see the problem. So the invalid pointer is
> Arc<FenceCtx…>? And potentially the <F> pointer (although we don't have
> a picture yet as to how that would be accessed through other callbacks.
>
> > If another thread obtains a pointer to the
> > FenceCtx via reading the fctx field of the DriverFence in parallel with
> > this, then that's not allowed because the drop_in_place() call has
> > exclusive access to that field.
>
> I think I have been asking in several of our meetings in the past
> whether it is actually a problem to access data that has been dropped()
> IF we know that drop does not cause UAF and the answer was kind of like
> a "well if it does not actually get freed…"
Ok, well, IMO the simplest approach is to say you can't. There may be
roundabout ways to do it, but I would suggest that we just ... don't.
> Anyways.
>
> It would seem the way to get this right is then
>
> synchronize_rcu();
> drop_in_palace(data);
>
>
> Agreed?
>
> This would then mean, however, that every time a fence drops, you have
> to wait a grace period.
>
> Or maybe stuff DriverFenceData into an RcuBox, too, and defer its
> dropping.
That would work, but I think we can do better and avoid the
synchronize_rcu() along these lines:
unsafe trait RcuRevocable {
unsafe fn rcu_revoke_in_place(ptr: *mut Self);
}
This trait provides a method that's like drop_in_place(), except that
when you use this destructor, the value remains usable for one grace
period. You could implement it for RcuBox, and for any Copy type, and
for ARef<T> when T is cleaned up with rcu, and probably also other
stuff.
Alice
next prev parent reply other threads:[~2026-06-02 11:44 UTC|newest]
Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-30 14:35 [PATCH 0/4] rust / dma_buf: Add abstractions for dma_fence Philipp Stanner
2026-05-30 14:35 ` [PATCH 1/4] rust: types: implement ForeignOwnable for ARef<T> Philipp Stanner
2026-05-30 14:45 ` sashiko-bot
2026-06-01 9:46 ` Alice Ryhl
2026-05-30 14:35 ` [PATCH 2/4] rust: rcu: add RcuBox type Philipp Stanner
2026-05-30 14:54 ` sashiko-bot
2026-05-30 15:08 ` Boqun Feng
2026-05-30 15:27 ` Danilo Krummrich
2026-06-01 7:56 ` Philipp Stanner
2026-06-01 13:41 ` Boqun Feng
2026-06-03 9:33 ` Philipp Stanner
2026-06-03 9:35 ` Alice Ryhl
2026-06-03 15:27 ` Boqun Feng
2026-06-03 17:36 ` Boqun Feng
2026-06-03 17:07 ` Boqun Feng
2026-05-30 14:35 ` [PATCH 3/4] rust: Add dma_fence abstractions Philipp Stanner
2026-05-30 15:06 ` sashiko-bot
2026-06-01 10:20 ` Alice Ryhl
2026-06-01 12:34 ` Philipp Stanner
2026-06-01 12:55 ` Alice Ryhl
2026-06-01 13:14 ` Philipp Stanner
2026-06-01 13:30 ` Philipp Stanner
2026-06-01 13:54 ` Alice Ryhl
2026-06-01 13:44 ` Alice Ryhl
2026-06-02 11:31 ` Philipp Stanner
2026-06-02 11:44 ` Alice Ryhl [this message]
2026-06-02 11:52 ` Philipp Stanner
2026-06-02 11:59 ` Alice Ryhl
2026-06-02 12:06 ` Philipp Stanner
2026-06-02 15:25 ` Alice Ryhl
2026-06-03 6:10 ` Philipp Stanner
2026-06-03 6:48 ` Boris Brezillon
2026-06-03 7:43 ` Philipp Stanner
2026-06-03 9:07 ` Philipp Stanner
2026-06-03 9:26 ` Alice Ryhl
2026-06-03 9:36 ` Philipp Stanner
2026-06-03 9:52 ` Boris Brezillon
2026-06-03 9:58 ` Boris Brezillon
2026-06-03 10:07 ` Philipp Stanner
2026-06-03 11:22 ` Boris Brezillon
2026-06-03 11:49 ` Philipp Stanner
2026-06-03 13:35 ` Boris Brezillon
2026-06-03 15:57 ` Danilo Krummrich
2026-06-03 16:34 ` Boris Brezillon
2026-06-03 19:43 ` Philipp Stanner
2026-06-03 16:51 ` Boris Brezillon
2026-05-30 15:16 ` Danilo Krummrich
2026-06-01 8:46 ` Philipp Stanner
2026-06-01 10:13 ` Danilo Krummrich
2026-06-01 10:36 ` Alice Ryhl
2026-06-01 10:59 ` Boris Brezillon
2026-06-01 11:17 ` Philipp Stanner
2026-06-01 12:35 ` Boris Brezillon
2026-06-01 12:26 ` Philipp Stanner
2026-06-01 12:39 ` Alice Ryhl
2026-06-01 12:47 ` Philipp Stanner
2026-06-01 13:22 ` Alice Ryhl
2026-06-01 13:23 ` Philipp Stanner
2026-06-01 13:27 ` Alice Ryhl
2026-06-01 12:37 ` Boris Brezillon
2026-06-03 16:41 ` Daniel Almeida
2026-06-03 17:14 ` Boris Brezillon
2026-06-04 0:43 ` Daniel Almeida
2026-06-04 8:15 ` Boris Brezillon
2026-06-05 7:56 ` Philipp Stanner
2026-06-05 16:00 ` Daniel Almeida
2026-06-05 16:02 ` Daniel Almeida
2026-06-05 15:51 ` Daniel Almeida
2026-05-30 14:35 ` [PATCH 4/4] MAINTAINERS: Add entry for Rust dma-buf Philipp Stanner
2026-05-30 15:20 ` Danilo Krummrich
2026-06-03 15:22 ` [PATCH 0/4] rust / dma_buf: Add abstractions for dma_fence Daniel Almeida
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=ah7CGySkyE7mSM8a@google.com \
--to=aliceryhl@google.com \
--cc=boris.brezillon@collabora.com \
--cc=linux-media@vger.kernel.org \
--cc=ojeda@kernel.org \
--cc=phasta@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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.