dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Philipp Stanner" <phasta@kernel.org>
Cc: dri-devel@lists.freedesktop.org, media-ci@linuxtv.org,
	ojeda@kernel.org, gary@garyguo.net
Subject: Re: [RFC PATCH v6 4/5] rust: DmaFence: Replace call_rcu() with synchronize_rcu()
Date: Fri, 16 Oct 2026 09:11:36 +0000	[thread overview]
Message-ID: <sashiko-outbox-174062@kernel.org> (raw)
In-Reply-To: <20261016085724.1031766-6-phasta@kernel.org>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] mm: memory leak of T::FenceDataType in DriverFence::drop due to dropping NonNull wrapper
- [High] locking: synchronize_rcu() in DriverFence::drop causes sleep-in-atomic
- [High] dma_fence: UAF of FenceContext strings via outliving Fence consumers
- [Low] doc: outdated safety comments referencing removed call_rcu()
--

commit 900eae064aeab4bf810f0f2081db8a2981b08546
Author: Philipp Stanner <phasta@kernel.org>

rust: DmaFence: Replace call_rcu() with synchronize_rcu()

This commit replaces the use of call_rcu() with synchronize_rcu() for dropping
DriverFence data. It removes the raw C callback and drops the data in-place
using drop_in_place().

> diff --git a/rust/kernel/dma_buf/dma_fence.rs b/rust/kernel/dma_buf/dma_fence.rs
> index b67121c7abd41..9efb84c00b6a2 100644
> --- a/rust/kernel/dma_buf/dma_fence.rs
> +++ b/rust/kernel/dma_buf/dma_fence.rs

[ ... ]

> @@ -973,59 +971,18 @@ fn drop(&mut self) {
>              return;
>          }

[Severity: Low]
Does this patch leave outdated safety comments in DriverFence::drop()?

The deferred call_rcu() has been removed from DriverFence::drop() and replaced
with synchronize_rcu(), but multiple SAFETY comments still reference it:

    // SAFETY: `guard` is valid until the `call_rcu()` below.
    let signaled: bool = unsafe { bindings::dma_fence_test_signaled_flag(guard.as_raw()) };

Could these comments be updated to prevent confusion during future maintenance?

>  
> +        // Make sure none of the fence backend_ops can access data anymore.
> +        //
> +        // TODO:
> +        // This would not be necessary if the C dma_fence backend were using a
> +        // spinlock to properly synchronize its signaled state. Fix it in C and
> +        // then remove synchronize_rcu().
> +        synchronize_rcu();

[Severity: High]
DriverFence implements Send + Sync, and Drop is called automatically when
variables go out of scope. Can this synchronize_rcu() be called from atomic
contexts like spinlock critical sections, interrupt handlers, or RCU read-side
critical sections?

Because synchronize_rcu() blocks and waits for a grace period, wouldn't dropping
a DriverFence in these contexts cause a might_sleep() lockdep warning or a
system deadlock on PREEMPT_RT?

[Severity: High]
This problem wasn't introduced by this patch, but does FenceContext have a
use-after-free issue with its strings?

The safety comment in get_driver_name() assumes it is only called on unsignaled
fences:

rust/kernel/dma_buf/dma_fence.rs:get_driver_name() {
    // SAFETY: The C backend only invokes this callback with `ptr` pointing
    // to a valid, unsignaled `bindings::dma_fence`.
    // ...
    let fctx = unsafe { Self::from_raw_fence(ptr) };

    fctx.driver_name.as_char_ptr()
}

However, sync_fill_fence_info() accesses the driver name when userspace queries
the sync_file info, and it calls get_driver_name() regardless of the signaled
state.

A consumer holding a sync_file fd can retain a reference to the Fence long after
the driver signals it and drops the FenceContext.

Furthermore, by replacing call_rcu() with synchronize_rcu() in
DriverFence::drop(), doesn't this completely defeat the rcu_barrier() in
FenceContext::drop() which was meant to wait for these tear-downs?

rust/kernel/dma_buf/dma_fence.rs:FenceContext::drop() {
    // Wait for the RCU callbacks in `DriverFence::drop`.
    rcu_barrier();
}

>  
>          // SAFETY: Valid because `self` is valid.
> -        let rcu_head_ptr = unsafe { &raw mut (*self.data.as_ptr()).rcu_head };
> +        unsafe { drop_in_place(&raw mut self.data) };

[Severity: High]
Does this actually drop the underlying data, or does it just drop the NonNull
pointer itself?

Since self.data is of type NonNull<DriverFenceData<'a, T>>, &raw mut self.data
produces a pointer to the NonNull wrapper (*mut NonNull<...>).

Because NonNull is Copy and has no Drop implementation, calling drop_in_place()
on this pointer is a no-op.

Will this permanently leak the actual user payload T::FenceDataType located at
(*self.data.as_ptr()).data?

> -        // SAFETY: `call_rcu()` is always safe to be called. `rcu_head_ptr` was
> -        // created validly above. The module must perform a `synchronize_rcu()`
> -        // or `rcu_barrier()` call to guard against module unload.
> -        unsafe { bindings::call_rcu(rcu_head_ptr, Some(drop_driver_fence_data::<T>)) };
> +        // SAFETY: The `synchronize_rcu()` above ensures all accessors are gone.
> +        unsafe { bindings::dma_fence_put(self.as_raw()) };
>      }
>  }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261016085724.1031766-2-phasta@kernel.org?part=4

  reply	other threads:[~2026-10-16  9:11 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-16  8:57 [RFC PATCH v6 0/5] rust: Add drm::JobQueue Philipp Stanner
2026-10-16  8:57 ` [RFC PATCH v6 1/5] rust: DmaFence: remove static lifetime Philipp Stanner
2026-10-16  9:06   ` sashiko-bot
2026-10-16  8:57 ` [RFC PATCH v6 2/5] rust: DmaFence: Implement Deref for FenceContext Philipp Stanner
2026-10-16  9:01   ` sashiko-bot
2026-10-16  8:57 ` [RFC PATCH v6 3/5] rust: DmaFence: Don't drop on signal Philipp Stanner
2026-10-16  9:04   ` sashiko-bot
2026-10-16  9:49   ` Alice Ryhl
2026-10-16  8:57 ` [RFC PATCH v6 4/5] rust: DmaFence: Replace call_rcu() with synchronize_rcu() Philipp Stanner
2026-10-16  9:11   ` sashiko-bot [this message]
2026-10-16  8:57 ` [RFC PATCH v6 5/5] rust: drm: Add JobQueue Philipp Stanner
2026-10-16  9:12   ` sashiko-bot

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=sashiko-outbox-174062@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gary@garyguo.net \
    --cc=media-ci@linuxtv.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox