All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Danilo Krummrich" <dakr@kernel.org>
Cc: "Alexandre Courbot" <acourbot@nvidia.com>,
	dri-devel@lists.freedesktop.org, ojeda@kernel.org,
	"Danilo Krummrich" <dakr@kernel.org>
Subject: Re: [PATCH 5/7] rust: drm: wrap fops open with RegistrationGuard
Date: Fri, 14 Aug 2026 23:29:45 +0000	[thread overview]
Message-ID: <20260814232945.A0A651F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260814230923.1292966-6-dakr@kernel.org>

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] Re-acquiring the DRM minor by ID in `fops_open` is vulnerable to a TOCTOU race, breaking type safety invariants.
--

--- Patch [5]: [PATCH 5/7] rust: drm: wrap fops open with RegistrationGuard ---
commit f19fe1023e3626e0af6b5b4f7cdaf8f59acc5f98
Author: Danilo Krummrich <dakr@kernel.org>

rust: drm: wrap fops open with RegistrationGuard

Add a Minor abstraction with RAII release and a fops_open() wrapper that
holds a RegistrationGuard (drm_dev_enter / drm_dev_exit) across the
entire drm_open() call. This guarantees that drm_dev_unplug() in 
Registration::drop() waits for the full open sequence to complete.

> diff --git a/rust/kernel/drm/device.rs b/rust/kernel/drm/device.rs
> index a2940e172073a..09903ed783e15 100644
> --- a/rust/kernel/drm/device.rs
> +++ b/rust/kernel/drm/device.rs

[ ... ]

> +    /// Wrapper for `fops.open` that holds a [`RegistrationGuard`] across the entire `drm_open()`
> +    /// call. This guarantees that `drm_dev_unplug()` in `Registration::drop()` waits for the full
> +    /// open sequence.
> +    extern "C" fn fops_open(inode: *mut bindings::inode, filp: *mut bindings::file) -> c_int {
> +        let f = || -> Result<c_int> {
> +            // SAFETY: `inode` is valid.
> +            let minor_id = unsafe { bindings::iminor(inode) };
> +            let minor = Minor::acquire(minor_id)?;
> +
> +            // SAFETY: `fops_open` is only installed for devices of type `T` (via `FOPS`).
> +            let _guard = (unsafe { minor.device::<T>() })

[Severity: High]
Can this sequence cause type confusion if the DRM minor ID is reassigned?

If a device T is unplugged concurrently with the open call, the minor_id
can be freed and reassigned to a different device U.

Since the VFS already resolved filp->f_op to T::fops_open during
drm_stub_open, the following sequence could occur:

1. VFS calls chrdev_open which resolves to drm_stub_open
2. drm_stub_open looks up minor_id, gets device T, and sets filp->f_op to
   T::FOPS
3. Device T is unplugged, and its minor_id is freed
4. Device U is hot-plugged, and drm_minor_alloc reuses the same minor_id
5. T::fops_open is called by VFS and invokes Minor::acquire(minor_id)
6. The returned minor now belongs to device U, not T

When minor.device::<T>() is called here, it unsafely downcasts Device<U>
to Device<T>. This violates Rust's type safety and aliasing invariants.
Is there a way to avoid looking up the minor by ID again to prevent this
race condition?

> +                .registration_guard()
> +                .ok_or(ENODEV)?;
> +
> +            // SAFETY: `inode` and `filp` are valid. The RegistrationGuard ensures the entire
> +            // `drm_open()` runs within the SRCU critical section.
> +            Ok(unsafe { bindings::drm_open(inode, filp) })
> +        };
> +
> +        match f() {
> +            Ok(ret) => ret,
> +            Err(e) => e.to_errno(),
> +        }
> +    }

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260814230923.1292966-1-dakr@kernel.org?part=5

  reply	other threads:[~2026-08-14 23:29 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-14 23:08 [PATCH 0/7] lifetime-parameterized DRM File private data Danilo Krummrich
2026-08-14 23:08 ` [PATCH 1/7] rust: drm: rename Ioctl device context to Userspace Danilo Krummrich
2026-08-14 23:09 ` [PATCH 2/7] rust: drm: gem: gate open/close callbacks with RegistrationGuard Danilo Krummrich
2026-08-14 23:21   ` sashiko-bot
2026-08-14 23:09 ` [PATCH 3/7] rust: drm: move file_operations from gem to device Danilo Krummrich
2026-08-14 23:22   ` sashiko-bot
2026-08-14 23:09 ` [PATCH 4/7] rust: fs: add iminor() helper Danilo Krummrich
2026-08-14 23:09 ` [PATCH 5/7] rust: drm: wrap fops open with RegistrationGuard Danilo Krummrich
2026-08-14 23:29   ` sashiko-bot [this message]
2026-08-14 23:09 ` [PATCH 6/7] rust: drm: make Driver::File lifetime-parameterized Danilo Krummrich
2026-08-14 23:23   ` sashiko-bot
2026-08-14 23:09 ` [PATCH 7/7] rust: drm: return impl PinInit from DriverFile::open() Danilo Krummrich

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=20260814232945.A0A651F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=acourbot@nvidia.com \
    --cc=dakr@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=ojeda@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.