[PATCH] rust_binder: enforce delivered death process ownership
Daniil Detkov <[email protected]> Wed, 05 Aug 2026 17:50:56 +0500
| Newsgroups | org.kernel.feeds.b4-sent,org.kernel.vger.linux-kernel,org.kernel.vger.rust-for-linux |
|---|---|
| Message-ID | <20260805-fix-rust-binder-death-ownership-v1-1-a89594c3b5db@proton.me> |
The delivered_links field of NodeDeath may only be linked into the
delivered_deaths list owned by NodeDeath::process. The existing safe
ProcessInner::death_delivered method does not enforce that relationship,
so safe Rust can violate the invariant relied on by a later unsafe list
removal.
Move the insertion boundary to Process and validate both the supplied
guard and the NodeDeath owner before mutating the list. Keep the existing
lock order and duplicate-insertion behavior unchanged.
Fixes: eafedbc7c050 ("rust_binder: add Rust Binder driver")
Closes: https://github.com/Rust-for-Linux/linux/issues/1238
Assisted-by: Codex:5.6-Sol
Signed-off-by: Daniil Detkov <[email protected]>
---
drivers/android/binder/node.rs | 6 +++++-
drivers/android/binder/process.rs | 23 +++++++++++++++--------
2 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/drivers/android/binder/node.rs b/drivers/android/binder/node.rs
index c10148e90..813718486 100644
--- a/drivers/android/binder/node.rs
+++ b/drivers/android/binder/node.rs
@@ -978,6 +978,10 @@ pub(crate) fn new(
))
}
+ pub(crate) fn belongs_to_process(&self, process: &Process) -> bool {
+ core::ptr::eq(&*self.process, process)
+ }
+
/// Sets the cleared flag to `true`.
///
/// It removes `self` from the node's death notification list if needed.
@@ -1103,7 +1107,7 @@ fn do_work(
}
// We're still holding the inner lock, so it cannot be aborted while we insert it into
// the delivered list.
- process_inner.death_delivered(self.clone());
+ process.death_delivered(&mut process_inner, self.clone());
BR_DEAD_BINDER
};
diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs
index cdd1a9079..5c5ce7c01 100644
--- a/drivers/android/binder/process.rs
+++ b/drivers/android/binder/process.rs
@@ -309,14 +309,6 @@ fn pull_delivered_death(&mut self, cookie: u64) -> Option<DArc<NodeDeath>> {
None
}
- pub(crate) fn death_delivered(&mut self, death: DArc<NodeDeath>) {
- if let Some(death) = ListArc::try_from_arc_or_drop(death) {
- self.delivered_deaths.push_back(death);
- } else {
- pr_warn!("Notification added to `delivered_deaths` twice.");
- }
- }
-
pub(crate) fn add_outstanding_txn(&mut self) {
self.outstanding_txns += 1;
}
@@ -920,6 +912,21 @@ pub(crate) fn get_node_from_handle(&self, handle: u32, strong: bool) -> Result<N
.clone(strong)
}
+ pub(crate) fn death_delivered(
+ &self,
+ inner: &mut Guard<'_, ProcessInner, SpinLockBackend>,
+ death: DArc<NodeDeath>,
+ ) {
+ assert!(core::ptr::eq(&self.inner, inner.lock_ref()));
+ assert!(death.belongs_to_process(self));
+
+ if let Some(death) = ListArc::try_from_arc_or_drop(death) {
+ inner.delivered_deaths.push_back(death);
+ } else {
+ pr_warn!("Notification added to `delivered_deaths` twice.");
+ }
+ }
+
pub(crate) fn remove_from_delivered_deaths(&self, death: &DArc<NodeDeath>) {
let mut inner = self.inner.lock();
// SAFETY: By the invariant on the `delivered_links` field, this is the right linked list.
---
base-commit: 075b74841bd0065a3bda3440873c747938e69b68
change-id: 20260805-fix-rust-binder-death-ownership-affac3fef3ab
Best regards,
--
Daniil Detkov <[email protected]>