From: sashiko-bot@kernel.org
To: "Markus Probst" <markus.probst@posteo.de>
Cc: ojeda@kernel.org, linux-serial@vger.kernel.org
Subject: Re: [PATCH v2 2/2] rust: serdev: Fix race condition on driver probe
Date: Sat, 05 Sep 2026 13:49:35 +0000 [thread overview]
Message-ID: <20260905134936.7C8FD1F00A3D@smtp.kernel.org> (raw)
In-Reply-To: <20260905-rust_serdev_fix-v2-2-35dfcd06ef2e@posteo.de>
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [Critical] Use-After-Free and Mutable Aliasing in `drvdata_drop` because memory is freed before clearing the driver data pointer.
- [High] `T::receive()` can run concurrently with `T::unbind()`, leading to a Use-After-Unbind race condition.
- [High] Circular deadlock between `probe_callback` and `receive_buf_callback`.
--
commit 67f5ed19e07ddf9c3ef694dbb2c1e962df051525
Author: Markus Probst <markus.probst@posteo.de>
rust: serdev: Fix race condition on driver probe
This commit fixes a race condition on driver probe failures by using
drvdata_drop() instead of drvdata_obtain(), ensuring the serdev device
is closed before the pointer to the driver data is set to null.
Closes: https://lore.kernel.org/linux-serial/20260903222159.70A911F000E9@smtp.kernel.org/
> diff --git a/rust/kernel/serdev.rs b/rust/kernel/serdev.rs
> index 17ca504b7f8d6..a12b1dea12aa1 100644
> --- a/rust/kernel/serdev.rs
> +++ b/rust/kernel/serdev.rs
> @@ -176,7 +176,7 @@ extern "C" fn probe_callback(sdev: *mut bindings::serdev_device) -> kernel::ffi:
> let private_data = unsafe { sdev.as_ref().drvdata_borrow::<PrivateData<'_, T>>() };
> let private_data = ScopeGuard::new_with_data(private_data, |_| {
> // SAFETY: We just set drvdata to `PrivateData<'_, T>`.
> - drop(unsafe { sdev.as_ref().drvdata_obtain::<PrivateData<'_, T>>() });
> + unsafe { sdev.as_ref().drvdata_drop::<PrivateData<'_, T>>() };
[Severity: Critical]
This is a pre-existing issue, but does calling drvdata_drop() here introduce
a use-after-free and mutable aliasing vulnerability?
Since drvdata_drop() executes drop() on the driver's private data and
deallocates the memory before calling dev_set_drvdata(..., null), the global
device pointer still references the freed memory.
If receive_buf_callback() is invoked concurrently by incoming serial data:
rust/kernel/serdev.rs:receive_buf_callback() {
...
let private_data = unsafe { sdev.as_ref().drvdata_borrow::<PrivateData<'_, T>>() };
...
}
It can fetch the still-non-null dangling pointer before it is cleared, and
block on the active mutex. Once drop() completes, receive_buf_callback()
would wake up and operate on freed memory.
> });
> let mut active = private_data.active.lock();
[Severity: High]
This isn't a bug introduced by this patch, but can holding this active mutex
across the T::probe() call result in a circular deadlock?
In probe_callback(), the active mutex is locked before invoking T::probe().
If a driver writes a command to the device and synchronously waits for a
response during probe, the incoming response would trigger
receive_buf_callback():
rust/kernel/serdev.rs:receive_buf_callback() {
...
let active = private_data.active.lock();
...
}
Since probe_callback() holds the lock and waits for the response, and
receive_buf_callback() receives the response but blocks indefinitely waiting
for the lock, does this structurally guarantee a deadlock for synchronous
probes?
[ ... ]
[Severity: High]
This is a pre-existing issue, but can T::receive() run concurrently with
T::unbind(), leading to a use-after-unbind race condition?
During device removal, remove_callback() calls T::unbind():
rust/kernel/serdev.rs:remove_callback() {
...
T::unbind(sdev, data_pinned);
}
It does not lock the active mutex, set it to false, or close the serdev
device prior to unbinding.
Consequently, incoming serial data can trigger receive_buf_callback(), which
evaluates the active check as true (since active is not cleared during
unbind):
rust/kernel/serdev.rs:receive_buf_callback() {
...
if !*active {
return length;
}
...
T::receive(sdev, data_pinned, buf)
}
This forwards the data to T::receive(), which can execute concurrently with
or after T::unbind(), accessing driver resources that are actively being
destroyed.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260905-rust_serdev_fix-v2-0-35dfcd06ef2e@posteo.de?part=2
next prev parent reply other threads:[~2026-09-05 13:49 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-05 13:30 [PATCH v2 0/2] rust: serdev: Mitigate race conditions Markus Probst
2026-09-05 13:30 ` [PATCH v2 1/2] rust: serdev: Fix race condition on driver unbind Markus Probst
2026-09-05 13:44 ` sashiko-bot
2026-09-05 13:47 ` Markus Probst
2026-09-05 14:16 ` Gary Guo
2026-09-05 17:44 ` Markus Probst
2026-09-05 13:30 ` [PATCH v2 2/2] rust: serdev: Fix race condition on driver probe Markus Probst
2026-09-05 13:49 ` sashiko-bot [this message]
2026-09-05 13:57 ` Markus Probst
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=20260905134936.7C8FD1F00A3D@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-serial@vger.kernel.org \
--cc=markus.probst@posteo.de \
--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.