Wrap the GEM object open and close callbacks with a RegistrationGuard (drm_dev_enter / drm_dev_exit) to ensure the driver callbacks only run while the parent bus device is bound.
If the device has been unbound, open returns -ENODEV and close silently returns. This prevents driver code from accessing device resources after unbind and is a prerequisite for making drm::Driver::File lifetime-parameterized, since GEM callbacks receive a &drm::File that could otherwise be used to access invalidated file private data. Signed-off-by: Danilo Krummrich <[email protected]> --- rust/kernel/drm/gem/mod.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/rust/kernel/drm/gem/mod.rs b/rust/kernel/drm/gem/mod.rs index 80d8f524f9d5..560403ca8e38 100644 --- a/rust/kernel/drm/gem/mod.rs +++ b/rust/kernel/drm/gem/mod.rs @@ -128,6 +128,14 @@ extern "C" fn open_callback<T: DriverObject>( raw_obj: *mut bindings::drm_gem_object, raw_file: *mut bindings::drm_file, ) -> core::ffi::c_int { + // SAFETY: `raw_obj` is a valid pointer to a `struct drm_gem_object` with a valid `dev`. + let dev: &drm::Device<T::Driver, drm::Userspace> = + unsafe { drm::Device::from_raw((*raw_obj).dev) }; + + let Some(_guard) = dev.registration_guard() else { + return ENODEV.to_errno(); + }; + // SAFETY: `open_callback` is only ever called with a valid pointer to a `struct drm_file`. let file = unsafe { DriverFile::<T>::from_raw(raw_file) }; @@ -148,6 +156,14 @@ extern "C" fn close_callback<T: DriverObject>( raw_obj: *mut bindings::drm_gem_object, raw_file: *mut bindings::drm_file, ) { + // SAFETY: `raw_obj` is a valid pointer to a `struct drm_gem_object` with a valid `dev`. + let dev: &drm::Device<T::Driver, drm::Userspace> = + unsafe { drm::Device::from_raw((*raw_obj).dev) }; + + let Some(_guard) = dev.registration_guard() else { + return; + }; + // SAFETY: `open_callback` is only ever called with a valid pointer to a `struct drm_file`. let file = unsafe { DriverFile::<T>::from_raw(raw_file) }; -- 2.55.0
