From: sashiko-bot@kernel.org
To: "Danilo Krummrich" <dakr@kernel.org>
Cc: linux-pci@vger.kernel.org, linux-serial@vger.kernel.org,
linux-usb@vger.kernel.org, ojeda@kernel.org, gary@garyguo.net
Subject: Re: [PATCH 5/7] rust: i2c: remove the unbind() callback
Date: Thu, 12 Nov 2026 01:19:10 +0000 [thread overview]
Message-ID: <sashiko-outbox-210060@kernel.org> (raw)
In-Reply-To: <20261112005455.1224352-6-dakr@kernel.org>
Thank you for your contribution! Sashiko AI review found 2 potential
issues to consider:
- [High] rust: i2c: dropping Driver::Data in post_unbind_rust runs after
devres release
- [Medium] rust: i2c: missing Sync impl for I2cClient<device::Bound>
--
commit 5a5ad706d767f7788672a5c38d2627a235e83cd2
Author: Danilo Krummrich <dakr@kernel.org>
rust: i2c: remove the unbind() callback
This commit removes i2c::Driver::unbind() and the adapter's remove
callback, documenting that I2C driver teardown should be performed in
Drop or PinnedDrop of Driver::Data.
> diff --git a/rust/kernel/i2c.rs b/rust/kernel/i2c.rs
> index b4ff25c830fc0..b15e73bf827ab 100644
> --- a/rust/kernel/i2c.rs
> +++ b/rust/kernel/i2c.rs
> @@ -123,7 +123,6 @@ unsafe fn register(
> unsafe {
> (*idrv.get()).driver.name = name.as_char_ptr();
> (*idrv.get()).probe = Some(Self::probe_callback);
> - (*idrv.get()).remove = Some(Self::remove_callback);
> (*idrv.get()).shutdown = Some(Self::shutdown_callback);
> (*idrv.get()).id_table = i2c_table;
> (*idrv.get()).driver.of_match_table = of_table;
> @@ -161,18 +160,6 @@ extern "C" fn probe_callback(idev: *mut bindings::i2c_client) -> kernel::ffi::c_
> })
> }
>
> - extern "C" fn remove_callback(idev: *mut bindings::i2c_client) {
> - // SAFETY: `idev` is a valid pointer to a `struct i2c_client`.
> - let idev = unsafe { &*idev.cast::<I2cClient<device::CoreInternal<'_>>>() };
> -
> - // SAFETY: `remove_callback` is only ever called after a successful call to
> - // `probe_callback`, hence it's guaranteed that `I2cClient::set_drvdata()` has been called
> - // and stored a `Pin<KBox<T::Data<'_>>>`.
> - let data = unsafe { idev.as_ref().drvdata_borrow::<T::Data<'_>>() };
> -
> - T::unbind(idev, data);
> - }
> -
> extern "C" fn shutdown_callback(idev: *mut bindings::i2c_client) {
> // SAFETY: `shutdown_callback` is only ever called for a valid `idev`
> let idev = unsafe { &*idev.cast::<I2cClient<device::CoreInternal<'_>>>() };
[Severity: High]
Does moving I2C driver teardown from remove_callback() to the Drop or
PinnedDrop destructor of Driver::Data cause driver teardown to run after
the client's devres resources have already been released?
i2c_device_probe() opens an unclosed devres group on client->dev before
calling driver->probe(), so devres entries registered for the client land
in client->devres_group_id. On unbind, __device_release_driver() calls
device_remove() -> i2c_device_remove() before device_unbind_cleanup() ->
post_unbind_rust():
drivers/i2c/i2c-core-base.c:i2c_device_remove() {
...
if (driver->remove) {
...
driver->remove(client);
}
debugfs_remove_recursive(client->debugfs);
devres_release_group(&client->dev, client->devres_group_id);
...
}
Because post_unbind_rust() drops Driver::Data in device_unbind_cleanup()
after i2c_device_remove() has already released client->devres_group_id,
all devres resources on the client are already revoked and dropped before
Driver::Data::drop() runs. If Driver::Data retains a &'bound reference
from Devres::access() or calls Devres::access() with a retained &'bound
Device<Bound> in its destructor, Devres::access() skips the Revocable
availability check and causes a use-after-free in safe Rust.
> @@ -312,6 +299,10 @@ pub trait Driver {
> type IdInfo: 'static;
>
> /// The type of the driver's bus device private data.
> + ///
> + /// Device teardown should be performed in [`Drop`] or [`PinnedDrop`](pin_init::PinnedDrop)
> + /// for this type. The `'bound` lifetime allows the data to retain device resources and a
> + /// [`I2cClient<device::Bound>`] reference for use during teardown.
> type Data<'bound>: Send + 'bound;
[Severity: Medium]
Can a driver actually store &'bound I2cClient<device::Bound> in
Driver::Data<'bound> as documented here?
Driver::Data<'bound> requires Send, so &'bound I2cClient<device::Bound>
is only Send if I2cClient<device::Bound> implements Sync. However, Sync
is only implemented for the default context parameter I2cClient
(I2cClient<device::Normal>), not for I2cClient<Ctx> or
I2cClient<device::Bound>, so storing &'bound I2cClient<device::Bound> in
Driver::Data<'bound> fails to compile.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261112005455.1224352-1-dakr@kernel.org?part=5
next prev parent reply other threads:[~2026-11-12 1:19 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-12 0:52 [PATCH 0/7] rust: treewide: remove driver unbind callbacks Danilo Krummrich
2026-11-12 0:52 ` [PATCH 1/7] rust: pci: remove the unbind() callback Danilo Krummrich
2026-11-12 1:19 ` sashiko-bot
2026-11-12 0:52 ` [PATCH 2/7] rust: platform: " Danilo Krummrich
2026-11-12 1:07 ` sashiko-bot
2026-11-12 0:52 ` [PATCH 3/7] rust: auxiliary: " Danilo Krummrich
2026-11-12 1:05 ` sashiko-bot
2026-11-12 0:52 ` [PATCH 4/7] rust: serdev: " Danilo Krummrich
2026-11-12 1:47 ` sashiko-bot
2026-11-12 0:52 ` [PATCH 5/7] rust: i2c: " Danilo Krummrich
2026-11-12 1:19 ` sashiko-bot [this message]
2026-11-12 0:53 ` [PATCH 6/7] rust: usb: remove the disconnect() callback Danilo Krummrich
2026-11-12 1:50 ` sashiko-bot
2026-11-12 0:53 ` [PATCH 7/7] rust: driver: document teardown through destructors Danilo Krummrich
2026-11-12 1:08 ` sashiko-bot
2026-11-12 9:47 ` [PATCH 0/7] rust: treewide: remove driver unbind callbacks Gary Guo
2026-11-12 14:37 ` Danilo Krummrich
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=sashiko-outbox-210060@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=dakr@kernel.org \
--cc=gary@garyguo.net \
--cc=linux-pci@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=ojeda@kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.