From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 94B5D3164B5; Tue, 17 Mar 2026 16:48:16 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773766096; cv=none; b=ex2XWS+nEfuyqKlT6Uv4+HmdvTlrZulkJePVMjrKLQbTkBYx2jse+HmtRpVtc21LAFDYa92EbmwyapBX8X859y30TAGQvuN/0jy9JUled3GDIo6yQtHOoLNyccEZ5LwGUaUUfozFf41zLa9rdJybPAiX/lnbP/Swj1RV+od6ZT8= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1773766096; c=relaxed/simple; bh=V6Hxa1xBOGncamyFrnMyegGlU+KVndYKBwnfFpIcly4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=I2CYkgBIyHsTLC9eVF1CrqNeSTjDrbNHy5vcDzt6Qq7s6CkS3SqZl/JTpVHbf/uHe1fTGGpgnkpR9o1P2IHduhvIgNb6jat/qtLqa5XnHyPoSWURzPp0KHCOziNTjpBzApQwEt2UjScucNeJ3zSFTICnznFRthJ6Gj2Xra9rOdo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b=JLBZDWbW; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.b="JLBZDWbW" Received: by smtp.kernel.org (Postfix) with ESMTPSA id E0C42C4CEF7; Tue, 17 Mar 2026 16:48:15 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1773766096; bh=V6Hxa1xBOGncamyFrnMyegGlU+KVndYKBwnfFpIcly4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=JLBZDWbWJv2gXltEqVQqc4hpe5tNgMoJdPBW/NK5hoQs3a2b2PzuZmiDHbvEc9b8V xW31VjM1DYWADpV0lpnnva3MlBsmwJxg93iiAPHmOKJl2Qxt4Ezgt7E5P5tsmzY6g7 UxIu4xEITVD8647UdBOIz7AIhPVvJzRBlKF3bafU= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, stable , Alice Ryhl , Carlos Llamas Subject: [PATCH 6.19 126/378] rust_binder: fix oneway spam detection Date: Tue, 17 Mar 2026 17:31:23 +0100 Message-ID: <20260317163011.650411247@linuxfoundation.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260317163006.959177102@linuxfoundation.org> References: <20260317163006.959177102@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore Precedence: bulk X-Mailing-List: stable@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 6.19-stable review patch. If anyone has any objections, please let me know. ------------------ From: Carlos Llamas commit 4fc87c240b8f30e22b7ebaae29d57105589e1c0b upstream. The spam detection logic in TreeRange was executed before the current request was inserted into the tree. So the new request was not being factored in the spam calculation. Fix this by moving the logic after the new range has been inserted. Also, the detection logic for ArrayRange was missing altogether which meant large spamming transactions could get away without being detected. Fix this by implementing an equivalent low_oneway_space() in ArrayRange. Note that I looked into centralizing this logic in RangeAllocator but iterating through 'state' and 'size' got a bit too complicated (for me) and I abandoned this effort. Cc: stable Cc: Alice Ryhl Fixes: eafedbc7c050 ("rust_binder: add Rust Binder driver") Signed-off-by: Carlos Llamas Reviewed-by: Alice Ryhl Link: https://patch.msgid.link/20260210232949.3770644-1-cmllamas@google.com Signed-off-by: Greg Kroah-Hartman --- drivers/android/binder/range_alloc/array.rs | 35 ++++++++++++++++++++++++++-- drivers/android/binder/range_alloc/mod.rs | 4 +-- drivers/android/binder/range_alloc/tree.rs | 18 +++++++------- 3 files changed, 44 insertions(+), 13 deletions(-) --- a/drivers/android/binder/range_alloc/array.rs +++ b/drivers/android/binder/range_alloc/array.rs @@ -118,7 +118,7 @@ impl ArrayRangeAllocator { size: usize, is_oneway: bool, pid: Pid, - ) -> Result { + ) -> Result<(usize, bool)> { // Compute new value of free_oneway_space, which is set only on success. let new_oneway_space = if is_oneway { match self.free_oneway_space.checked_sub(size) { @@ -146,7 +146,38 @@ impl ArrayRangeAllocator { .ok() .unwrap(); - Ok(insert_at_offset) + // Start detecting spammers once we have less than 20% + // of async space left (which is less than 10% of total + // buffer size). + // + // (This will short-circuit, so `low_oneway_space` is + // only called when necessary.) + let oneway_spam_detected = + is_oneway && new_oneway_space < self.size / 10 && self.low_oneway_space(pid); + + Ok((insert_at_offset, oneway_spam_detected)) + } + + /// Find the amount and size of buffers allocated by the current caller. + /// + /// The idea is that once we cross the threshold, whoever is responsible + /// for the low async space is likely to try to send another async transaction, + /// and at some point we'll catch them in the act. This is more efficient + /// than keeping a map per pid. + fn low_oneway_space(&self, calling_pid: Pid) -> bool { + let mut total_alloc_size = 0; + let mut num_buffers = 0; + + // Warn if this pid has more than 50 transactions, or more than 50% of + // async space (which is 25% of total buffer size). Oneway spam is only + // detected when the threshold is exceeded. + for range in &self.ranges { + if range.state.is_oneway() && range.state.pid() == calling_pid { + total_alloc_size += range.size; + num_buffers += 1; + } + } + num_buffers > 50 || total_alloc_size > self.size / 4 } pub(crate) fn reservation_abort(&mut self, offset: usize) -> Result { --- a/drivers/android/binder/range_alloc/mod.rs +++ b/drivers/android/binder/range_alloc/mod.rs @@ -188,11 +188,11 @@ impl RangeAllocator { self.reserve_new(args) } Impl::Array(array) => { - let offset = + let (offset, oneway_spam_detected) = array.reserve_new(args.debug_id, args.size, args.is_oneway, args.pid)?; Ok(ReserveNew::Success(ReserveNewSuccess { offset, - oneway_spam_detected: false, + oneway_spam_detected, _empty_array_alloc: args.empty_array_alloc, _new_tree_alloc: args.new_tree_alloc, _tree_alloc: args.tree_alloc, --- a/drivers/android/binder/range_alloc/tree.rs +++ b/drivers/android/binder/range_alloc/tree.rs @@ -164,15 +164,6 @@ impl TreeRangeAllocator { self.free_oneway_space }; - // Start detecting spammers once we have less than 20% - // of async space left (which is less than 10% of total - // buffer size). - // - // (This will short-circut, so `low_oneway_space` is - // only called when necessary.) - let oneway_spam_detected = - is_oneway && new_oneway_space < self.size / 10 && self.low_oneway_space(pid); - let (found_size, found_off, tree_node, free_tree_node) = match self.find_best_match(size) { None => { pr_warn!("ENOSPC from range_alloc.reserve_new - size: {}", size); @@ -203,6 +194,15 @@ impl TreeRangeAllocator { self.free_tree.insert(free_tree_node); } + // Start detecting spammers once we have less than 20% + // of async space left (which is less than 10% of total + // buffer size). + // + // (This will short-circuit, so `low_oneway_space` is + // only called when necessary.) + let oneway_spam_detected = + is_oneway && new_oneway_space < self.size / 10 && self.low_oneway_space(pid); + Ok((found_off, oneway_spam_detected)) }