[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 {