From 0a69ac25bd596d50823d530d0a2004336668c0df Mon Sep 17 00:00:00 2001 From: Eliot Courtney Date: Fri, 1 May 2026 19:49:37 +0900 Subject: [PATCH] rust: drm: fix unsound initialization in drm::Device::new If pinned initialization of drm::Device::Data fails, it calls drm::Device::release via drm_dev_put. This materializes a reference to &drm::Device, but it's not fully constructed yet, because initializing `data` failed. It should not be dropped either. Instead, if pinned initialization fails, make sure drm::Device::release isn't called. Fixes: 2e9fdbe5ec7a ("rust: drm: device: drop_in_place() the drm::Device in release()") Signed-off-by: Eliot Courtney Reviewed-by: Gary Guo Link: https://patch.msgid.link/20260501-fix-drm-1-v2-1-5c4f681837bc@nvidia.com Signed-off-by: Danilo Krummrich --- rust/kernel/drm/device.rs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/rust/kernel/drm/device.rs b/rust/kernel/drm/device.rs index adbafe8db54d..403fc35353c7 100644 --- a/rust/kernel/drm/device.rs +++ b/rust/kernel/drm/device.rs @@ -119,13 +119,20 @@ pub fn new(dev: &device::Device, data: impl PinInit) -> Result()); + // Use a temporary vtable without a `release` callback until `data` is initialized, so + // init failure can release the DRM device without dropping uninitialized fields. + let alloc_vtable = bindings::drm_driver { + release: None, + ..Self::VTABLE + }; + // SAFETY: - // - `VTABLE`, as a `const` is pinned to the read-only section of the compilation, + // - `alloc_vtable` reference remains valid until no longer used, // - `dev` is valid by its type invarants, let raw_drm: *mut Self = unsafe { bindings::__drm_dev_alloc( dev.as_raw(), - &Self::VTABLE, + &alloc_vtable, layout.size(), mem::offset_of!(Self, dev), ) @@ -133,6 +140,10 @@ pub fn new(dev: &device::Device, data: impl PinInit) -> Result) -> Result