[PATCH v3 4/23] rust: drm: reject cross-device GEM handle creation

Mike Lothian <[email protected]>
Newsgroups org.kernel.vger.rust-for-linux,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
The Rust type bounds prove that a GEM object and file use the same
driver implementation, but one driver can own multiple DRM device
instances. drm_gem_handle_create() also requires the object and file
to belong to the same instance.

Expose the owning device pointer within the DRM crate and return
EINVAL for a mismatched instance.

Fixes: c284d3e42338 ("rust: drm: gem: Add GEM object abstraction")

Assisted-by: Claude:claude-opus-5
Signed-off-by: Mike Lothian <[email protected]>
---
 rust/kernel/drm/file.rs    | 7 +++++++
 rust/kernel/drm/gem/mod.rs | 7 +++++++
 2 files changed, 14 insertions(+)

diff --git a/rust/kernel/drm/file.rs b/rust/kernel/drm/file.rs
index 10160601ce5a..0abb7813f011 100644
--- a/rust/kernel/drm/file.rs
+++ b/rust/kernel/drm/file.rs
@@ -45,6 +45,13 @@ pub(super) fn as_raw(&self) -> *mut bindings::drm_file {
         self.0.get()
     }
 
+    /// Return the DRM device that owns this open file.
+    pub(crate) fn device_raw(&self) -> *mut bindings::drm_device {
+        // SAFETY: An open `drm_file` has a valid `minor`, whose `dev` pointer remains valid for
+        // the lifetime of the file.
+        unsafe { (*(*self.as_raw()).minor).dev }
+    }
+
     fn driver_priv(&self) -> *mut T {
         // SAFETY: By the type invariants of `Self`, `self.as_raw()` is always valid.
         unsafe { (*self.as_raw()).driver_priv }.cast()
diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs
index 60491e5521e4..334e946833fb 100644
--- a/rust/kernel/drm/gem/mod.rs
+++ b/rust/kernel/drm/gem/mod.rs
@@ -186,6 +186,13 @@ fn create_handle<D, F>(&self, file: &drm::File<F>) -> Result<u32>
         D: drm::Driver<Object = Self, File = F>,
         F: drm::file::DriverFile<Driver = D>,
     {
+        // The associated-type bounds prove a common driver type; separately reject another
+        // instance of that driver before passing the pair to the C API.
+        // SAFETY: `self.as_raw()` is a valid GEM object by the trait invariant.
+        if unsafe { (*self.as_raw()).dev } != file.device_raw() {
+            return Err(EINVAL);
+        }
+
         let mut handle: u32 = 0;
         // SAFETY: The arguments are all valid per the type invariants.
         to_result(unsafe {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.