From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4783C38C2DE for ; Fri, 3 Jul 2026 11:25:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.74 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783077926; cv=none; b=XtMO4Ty2p/C9aLRjpS5qjJBTn8Dm/B7JxkQI8hx8XY+srfUmneZPGcJkjQ3qnqeCIasbLzK7I+J3W8y6/wbEU4wRpnwk9uELGqlVuSB7U5kiLZ3ozfoR4MG5+8uhCyEiy9guAKp6rNVDMKQ//C9ERPLMFtPmVn12CvfVAAvxBgE= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1783077926; c=relaxed/simple; bh=sfxXRBCjYtWmQWoIrPpXmCIm6bSqjkrDfV1GfKq6d/M=; h=Date:Mime-Version:Message-ID:Subject:From:To:Cc:Content-Type; b=I97NrkcCWCMExgSzIRgArLhnSXwAEe9RkHUcE7bpE0GC2r0LvTeqe1RSqmEbT37LA+q1ihm4BXNY868h2ZxF4/8f+5Ff9McYfXeJ9fFl46hGPG81tqBmk5isLztY7Ul9NsQa8VAuoKnzFjt92OIdoyeyNJBFoFTXDTKDiCcrheY= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=ddSrRZOw; arc=none smtp.client-ip=209.85.221.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--aliceryhl.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="ddSrRZOw" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-471c76f357aso459638f8f.0 for ; Fri, 03 Jul 2026 04:25:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1783077919; x=1783682719; darn=vger.kernel.org; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date:message-id:reply-to; bh=SCqXp9VH3iBuz5exRugWLU1vY3GeeIWYYL2H+UtC82c=; b=ddSrRZOwbdRbmEWiEp0/ioNogBWY4YtzH5HG8sqJie/RDSl9/Qm8NzZa/zKWN7Hzo7 jLpIzpHgKmWyzBPSD6GBf3KNaArn8akPKDDKalFLo/Pq2Y2q9XWifYpGjKUDJlmK09Kv b7lBOIvxJ6o7kShYQ9A5VsBLJfhe4tOMk2w6TzS60uMkKAI5ygs2EGRwcQLLncxfzf5J vuEddDyZDvT82zhviMMhwelsbficndHKY+gqDxMenk+2qxFQxyja7yXaeLVtA8JTyPQ2 JeKDtsuUPo2nME+yxTUui5FqfkCS58k94FbenbRoFQe71pIGTtq2E9k2emLWgov84Pvg LDYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1783077919; x=1783682719; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=SCqXp9VH3iBuz5exRugWLU1vY3GeeIWYYL2H+UtC82c=; b=GEAkKToAnly/SXDZ+2fArVnb6VrQO/PYgOR1ZvV9fsVPue29dW357N1+22+1HvEmK+ zfYqMnuba4EVkY+pdt879ruuOiap+CyhzNsTYv+1cD52SxmLvwwcUSMEunHdoSsydpe6 OInLD128gRLxMTwE2A+hzeLeCyxbuwaCAbQ2hkjDtvUB9ukhj1wy2AQ9GEuhsVB73cZJ 85XimSFI7ab4n6rZJ41ahPdKr3SszY+OJNuSA1yEx4S1kbm6DkojlCle/PP1JFr36DTL 8mYYdictLjiV0ju+TNKUUnUwCWLiWUcFqK60G9Zwda23HdbWidGUyfAzQM86sdDKbmWr y4ZA== X-Forwarded-Encrypted: i=1; AFNElJ87hKpDttWSqd142Gz7BhXTaALjVgIti9SUDbt0ZYqW3SgFPgX5Bk+fu5YZT68zDXec0ciBXMi6IcFho8c=@vger.kernel.org X-Gm-Message-State: AOJu0YyHYS8+jejfA7oaTikXqtwcTF87phf1xNPB97tmqd1wqewq6ju4 umvouBAeHXK0QPXGrTly+YosV4zUCFWp5tiPoK9RSm/Rmm0zgi/hqllnE1IRMsMG7WPtrIROb51 DZ/+tJFb/EJKOohpDzA== X-Received: from wmim5.prod.google.com ([2002:a7b:cb85:0:b0:48a:5334:11e]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:5307:b0:493:c3e0:c4 with SMTP id 5b1f17b1804b1-493c3e00358mr124550875e9.22.1783077918954; Fri, 03 Jul 2026 04:25:18 -0700 (PDT) Date: Fri, 03 Jul 2026 11:25:12 +0000 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 X-B4-Tracking: v=1; b=H4sIABecR2oC/42OQW7CMBRErxJ5zY9iG2zCqvdAXcRhHCyRmNrBa otyd4yjSu2qLN9o9GbuLCI4RHao7iwguej8lEFuKtafu2kAuVNmJhqhGtW0FDD6BLIB+Ab56Se Y/AkkG2hhrTJbBZYV1wDrPov++L5ywMctr8xryEwXQb0fRzcfqqRrQaHn7Nk9uzj78FWeJV7Kr 51InDhZpa00rbEw+7fB++GCOs8UcxK/bHz3j01kWyuN5Fop6O6vbVmWByWBcVVDAQAA X-Change-Id: 20260609-remove-freeze-on-remove-node-30e72ff6b46e X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=5488; i=aliceryhl@google.com; h=from:subject:message-id; bh=sfxXRBCjYtWmQWoIrPpXmCIm6bSqjkrDfV1GfKq6d/M=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBqR5wZHnyMu1qcxkCkPNHv2pA4tDN4jrzslXoIQ NcMeKXEhueJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCakecGQAKCRAEWL7uWMY5 RkhYD/9A47eYXut4U2kxrBjIgODE/wd73gFaO9Q7AHtsfpft2jQpE/EjXqK9hjQdZW881TEh1Bs Q1TbhBdBWYOFT1eNZTxaldlYVYuZ558DXn+jDf5B4n/IP92xZnbjXorz4sFLFs19CQTbOsxsF82 JNLCxY1IiFv3TDPEx9kR7NplkdIaTQXyfE+aEDvEA1bV0+Hamdep/6aejHEQDL3r520TYLg/MVW /MUELppxuDNzWaIu6jYT/bR3IgEZuea371v9bh8/dGOWx82CEEihl/W3/gWP8wJMfwOXOr2JDtF pUSL9akKdKIyEZwzSkkYkTNzQqMjF94r2F0VQ3ZWblkM/BkxklsBc1GWMtFULXD1zDHlFiCCZUr zTM6kPNEJ1vtIIYuDLJILaxG4bxMpH4pa4pJMMrh4FVJWGqbd8Ph2cjfdV1ctNb/wKR4hMiLK/c zw2kmL8ZJONqRZaxHaQq2O3gzOfRcGDAYHfQC8y7+Z57z3droF3PddzPX0YcuxLTE+LqVKvZIlD 28uIcJKC8Bf3sS8Ymm1wHI55PDvIqW3HwOVw39VaXCCgW+KvtBnB7GbmYVzM1jzDCfr4bQ+GM2F 93i7Te1fO8eTYvAPMB4hBG75YSkqKkszm1DtqxjyhjLzfQ6ioPYn+pI4a2tq2D7KtWBf4dg/tMa XkrBwxelV2+lKuw== X-Mailer: b4 0.14.3 Message-ID: <20260703-remove-freeze-on-remove-node-v3-1-6e0c4547af46@google.com> Subject: [PATCH v3] rust_binder: clear freeze listener on node removal From: Alice Ryhl To: Greg Kroah-Hartman , Carlos Llamas Cc: Miguel Ojeda , Boqun Feng , Gary Guo , "=?utf-8?q?Bj=C3=B6rn_Roy_Baron?=" , Benno Lossin , Andreas Hindborg , Alice Ryhl , Trevor Gross , Danilo Krummrich , rust-for-linux@vger.kernel.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org Content-Type: text/plain; charset="utf-8" Generally userspace is supposed to explicitly clear freeze listeners before they drop the refcount on the node ref to zero, but there's nothing forcing that. Currently, in this scenario the freeze listener remains in the freeze_listeners rbtree and in the remote node's freeze listener list, even though the ref for which the listener is registered is gone. This could potentially lead to a memory leak due to a refcount cycle. Thus, remove the freeze listener in this scenario. Cc: stable@vger.kernel.org Fixes: eafedbc7c050 ("rust_binder: add Rust Binder driver") Signed-off-by: Alice Ryhl --- Changes in v3: - Get rid of dependency. - Rebase. - Link to v2: https://lore.kernel.org/r/20260615-remove-freeze-on-remove-node-v2-1-93b31766e7a8@google.com Changes in v2: - Rebase on v3 of parent series. - Link to v1: https://lore.kernel.org/r/20260609-remove-freeze-on-remove-node-v1-1-f67f3b9bfeb8@google.com --- drivers/android/binder/freeze.rs | 11 +++++++++-- drivers/android/binder/node.rs | 10 ++++++---- drivers/android/binder/process.rs | 12 +++++++++++- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/drivers/android/binder/freeze.rs b/drivers/android/binder/freeze.rs index 53b60035639a..f4df14568b25 100644 --- a/drivers/android/binder/freeze.rs +++ b/drivers/android/binder/freeze.rs @@ -154,10 +154,17 @@ fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> { } impl FreezeListener { - pub(crate) fn on_process_exit(&self, proc: &Arc) { + /// Called when this freeze listener is cleared abnormally. + /// + /// This occurs either because the process exited or because the process dropped its last + /// refcount on the node ref without explicitly removing the freeze listener first. + /// + /// The returned `KVVec` is just a value that should be dropped outside of the lock. + pub(crate) fn on_process_cleanup(&self, proc: &Process) -> KVVec> { if !self.is_clearing { - self.node.remove_freeze_listener(proc); + return self.node.remove_freeze_listener(proc); } + KVVec::new() } } diff --git a/drivers/android/binder/node.rs b/drivers/android/binder/node.rs index 69f757ff7461..c10148e9069f 100644 --- a/drivers/android/binder/node.rs +++ b/drivers/android/binder/node.rs @@ -682,12 +682,13 @@ pub(crate) fn add_freeze_listener( } } - pub(crate) fn remove_freeze_listener(&self, p: &Arc) { - let _unused_capacity; + pub(crate) fn remove_freeze_listener(&self, p: &Process) -> KVVec> { let mut guard = self.owner.inner.lock(); let inner = self.inner.access_mut(&mut guard); let len = inner.freeze_list.len(); - inner.freeze_list.retain(|proc| !Arc::ptr_eq(proc, p)); + inner + .freeze_list + .retain(|proc| !core::ptr::eq::(&**proc, p)); if len == inner.freeze_list.len() { pr_warn!( "Could not remove freeze listener for {}\n", @@ -695,8 +696,9 @@ pub(crate) fn remove_freeze_listener(&self, p: &Arc) { ); } if inner.freeze_list.is_empty() { - _unused_capacity = mem::take(&mut inner.freeze_list); + return mem::take(&mut inner.freeze_list); } + KVVec::new() } pub(crate) fn freeze_list<'a>(&'a self, guard: &'a ProcessInner) -> &'a [Arc] { diff --git a/drivers/android/binder/process.rs b/drivers/android/binder/process.rs index ca664fda8e81..cdd1a9079726 100644 --- a/drivers/android/binder/process.rs +++ b/drivers/android/binder/process.rs @@ -946,6 +946,8 @@ pub(crate) fn update_ref( // To preserve original binder behaviour, we only fail requests where the manager tries to // increment references on itself. + let _to_free_freeze_listener; + let _to_free_freeze_listener_cleanup; let mut refs = self.node_refs.lock(); if let Some(info) = refs.by_handle.get_mut(&handle) { if info.node_ref().update(inc, strong) { @@ -961,6 +963,14 @@ pub(crate) fn update_ref( unsafe { info.node_ref2().node.remove_node_info(info) }; let id = info.node_ref().node.global_id(); + + if let Some(freeze) = *info.freeze() { + if let Some(fl) = refs.freeze_listeners.remove(&freeze) { + _to_free_freeze_listener_cleanup = fl.on_process_cleanup(&self); + _to_free_freeze_listener = fl; + } + } + refs.by_handle.remove(&handle); refs.by_node.remove(&id); refs.handle_is_present.release_id(handle as usize); @@ -1384,7 +1394,7 @@ fn deferred_release(self: Arc) { // Clean up freeze listeners. let freeze_listeners = take(&mut self.node_refs.lock().freeze_listeners); for listener in freeze_listeners.values() { - listener.on_process_exit(&self); + listener.on_process_cleanup(&self); } drop(freeze_listeners); --- base-commit: 728e68a889bcf257b1e67298b12c360e5c3a13e0 change-id: 20260609-remove-freeze-on-remove-node-30e72ff6b46e Best regards, -- Alice Ryhl