diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2026-01-24 10:13:22 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2026-01-24 10:13:22 -0800 |
| commit | 5dbeeb268b63ea2d9795b3e5e8ffb48c236f5bb0 (patch) | |
| tree | 56ec07e5dc3759334915e80ed2234a5e18f448b1 /rust/kernel/usb.rs | |
| parent | 12a0094839d095e6cfd23dc5f5336d260a363331 (diff) | |
| parent | a995fe1a3aa78b7d06cc1cc7b6b8436c5e93b07f (diff) | |
Merge tag 'driver-core-6.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core
Pull driver core fixes from Danilo Krummrich:
- Always inline I/O and IRQ methods using build_assert!() to avoid
false positive build errors
- Do not free the driver's device private data in I2C shutdown()
avoiding race conditions that can lead to UAF bugs
- Drop the driver's device private data after the driver has been
fully unbound from its device to avoid UAF bugs from &Device<Bound>
scopes, such as IRQ callbacks
* tag 'driver-core-6.19-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/driver-core/driver-core:
rust: driver: drop device private data post unbind
rust: driver: add DriverData type to the DriverLayout trait
rust: driver: add DEVICE_DRIVER_OFFSET to the DriverLayout trait
rust: driver: introduce a DriverLayout trait
rust: auxiliary: add Driver::unbind() callback
rust: i2c: do not drop device private data on shutdown()
rust: irq: always inline functions using build_assert with arguments
rust: io: always inline functions using build_assert with arguments
Diffstat (limited to 'rust/kernel/usb.rs')
| -rw-r--r-- | rust/kernel/usb.rs | 27 |
1 files changed, 18 insertions, 9 deletions
diff --git a/rust/kernel/usb.rs b/rust/kernel/usb.rs index d10b65e9fb6a..67ce5c85c619 100644 --- a/rust/kernel/usb.rs +++ b/rust/kernel/usb.rs @@ -27,13 +27,22 @@ use core::{ /// An adapter for the registration of USB drivers. pub struct Adapter<T: Driver>(T); -// SAFETY: A call to `unregister` for a given instance of `RegType` is guaranteed to be valid if +// SAFETY: +// - `bindings::usb_driver` is a C type declared as `repr(C)`. +// - `T` is the type of the driver's device private data. +// - `struct usb_driver` embeds a `struct device_driver`. +// - `DEVICE_DRIVER_OFFSET` is the correct byte offset to the embedded `struct device_driver`. +unsafe impl<T: Driver + 'static> driver::DriverLayout for Adapter<T> { + type DriverType = bindings::usb_driver; + type DriverData = T; + const DEVICE_DRIVER_OFFSET: usize = core::mem::offset_of!(Self::DriverType, driver); +} + +// SAFETY: A call to `unregister` for a given instance of `DriverType` is guaranteed to be valid if // a preceding call to `register` has been successful. unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { - type RegType = bindings::usb_driver; - unsafe fn register( - udrv: &Opaque<Self::RegType>, + udrv: &Opaque<Self::DriverType>, name: &'static CStr, module: &'static ThisModule, ) -> Result { @@ -45,14 +54,14 @@ unsafe impl<T: Driver + 'static> driver::RegistrationOps for Adapter<T> { (*udrv.get()).id_table = T::ID_TABLE.as_ptr(); } - // SAFETY: `udrv` is guaranteed to be a valid `RegType`. + // SAFETY: `udrv` is guaranteed to be a valid `DriverType`. to_result(unsafe { bindings::usb_register_driver(udrv.get(), module.0, name.as_char_ptr()) }) } - unsafe fn unregister(udrv: &Opaque<Self::RegType>) { - // SAFETY: `udrv` is guaranteed to be a valid `RegType`. + unsafe fn unregister(udrv: &Opaque<Self::DriverType>) { + // SAFETY: `udrv` is guaranteed to be a valid `DriverType`. unsafe { bindings::usb_deregister(udrv.get()) }; } } @@ -94,9 +103,9 @@ impl<T: Driver + 'static> Adapter<T> { // SAFETY: `disconnect_callback` is only ever called after a successful call to // `probe_callback`, hence it's guaranteed that `Device::set_drvdata()` has been called // and stored a `Pin<KBox<T>>`. - let data = unsafe { dev.drvdata_obtain::<T>() }; + let data = unsafe { dev.drvdata_borrow::<T>() }; - T::disconnect(intf, data.as_ref()); + T::disconnect(intf, data); } } |
