FAILED: patch "[PATCH] rust_binder: fix BINDER_GET_EXTENDED_ERROR" failed to apply to 6.18-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x 77bfebf110773f5a0d6b5ff8110896adb2c9c335
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026071331-obstruct-sprig-4ee1@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 77bfebf110773f5a0d6b5ff8110896adb2c9c335 Mon Sep 17 00:00:00 2001
From: Alice Ryhl <[email protected]>
Date: Fri, 5 Jun 2026 11:13:50 +0000
Subject: [PATCH] rust_binder: fix BINDER_GET_EXTENDED_ERROR
This code currently copies the ExtendedError struct to the stack, modifies the copy, and then doesn't modify the original. Thus, fix it.
Furthermore, errors when replying must be delivered directly to the remote thread, so update deliver_reply() to take an extended error argument.
drivers/android/binder/error.rs +5 -8
@@ -73,20 +73,17 @@ impl fmt::Debug for BinderError {fn fmt (&self, f: &mut fmt::Formatter <'_>) -> fmt::Result {match self.reply {BR_FAILED_REPLY =>match self.source.as_ref () { -Some (source) => f - .debug_struct ("BR_FAILED_REPLY" ) - .field ("source" , source) - .finish (), +Some (source) => source.fmt (f),None => f.pad ("BR_FAILED_REPLY" ), },BR_DEAD_REPLY => f.pad ("BR_DEAD_REPLY" ),BR_FROZEN_REPLY => f.pad ("BR_FROZEN_REPLY" ),BR_TRANSACTION_PENDING_FROZEN => f.pad ("BR_TRANSACTION_PENDING_FROZEN" ),BR_TRANSACTION_COMPLETE => f.pad ("BR_TRANSACTION_COMPLETE" ), - _ => f - .debug_struct ("BinderError" ) - .field ("reply" , &self.reply) - .finish (), + _ =>match self.source.as_ref () { +Some (source) => source.fmt (f), +None => self.reply.fmt (f), + }, } } }
drivers/android/binder/thread.rs +46 -19
135 lines not on this page · raw message
drivers/android/binder/transaction.rs +7 -8
@@ -42,6 +42,7 @@ pub(crate) struct TransactionInfo { pub(crate) reply: u32, pub(crate) oneway_spam_suspect: bool, pub(crate) is_reply: bool, + pub(crate) debug_id: usize, }impl TransactionInfo {
@@ -93,7 +94,6 @@ pub(crate) fn new( from: &Arc<Thread>, info: &mut TransactionInfo, ) -> BinderResult<DLArc<Self>> { -let debug_id =super ::next_debug_id ();let allow_fds = node_ref.node.flags &FLAT_BINDER_FLAG_ACCEPTS_FDS !=0 ;let txn_security_ctx = node_ref.node.flags &FLAT_BINDER_FLAG_TXN_SECURITY_CTX !=0 ;let mut txn_security_ctx_off =if txn_security_ctx {Some (0 ) }else {None };
@@ -101,7 +101,7 @@ pub(crate) fn new(let mut alloc =match from.copy_transaction_data ( to.clone (), info, - debug_id, + info.debug_id, allow_fds, txn_security_ctx_off.as_mut (), ) {
@@ -128,7 +128,7 @@ pub(crate) fn new(let data_address = alloc.ptr; Ok(DTRWrap::arc_pin_init(pin_init!(Transaction { - debug_id, + debug_id: info.debug_id, target_node: Some(target_node), from_parent, sender_euid: Kuid::current_euid(),
@@ -152,9 +152,8 @@ pub(crate) fn new_reply( info: &mut TransactionInfo, allow_fds: bool, ) -> BinderResult<DLArc<Self>> { -let debug_id =super ::next_debug_id ();let mut alloc = -match from.copy_transaction_data (to.clone (), info, debug_id, allow_fds,None ) { +match from.copy_transaction_data (to.clone (), info, info.debug_id, allow_fds,None ) {Ok (alloc) => alloc,Err (err) => {pr_warn! ("Failure in copy_transaction_data: {:?}" , err);
@@ -165,7 +164,7 @@ pub(crate) fn new_reply( alloc.set_info_clear_on_drop (); } Ok(DTRWrap::arc_pin_init(pin_init!(Transaction { - debug_id, + debug_id: info.debug_id, target_node: None, from_parent: None, sender_euid: Kuid::current_euid(),
@@ -394,7 +393,7 @@ fn do_work(let send_failed_reply =ScopeGuard ::new (|| {if self.target_node.is_some () && self.flags &TF_ONE_WAY ==0 {let reply =Err (BR_FAILED_REPLY ); - self.from.deliver_reply (reply, &self); + self.from.deliver_reply (reply, &self,None ); } self.drop_outstanding_txn (); });
@@ -478,7 +477,7 @@ fn cancel(self: DArc<Self>) {// If this is not a reply or oneway transaction, then send a dead reply. if self.target_node.is_some () && self.flags &TF_ONE_WAY ==0 {let reply =Err (BR_DEAD_REPLY ); - self.from.deliver_reply (reply, &self); + self.from.deliver_reply (reply, &self,None ); } self.drop_outstanding_txn ();
Alice Ryhl
maintainerPATCH 1/2 rust_binder: introduce TransactionInfo
Rust Binder exposes information about transactions that are sent in various ways: printing to the kernel log, tracepoints, files in binderfs, and the upcoming netlink support. Currently all these mechanisms use disparate ways of obtaining the same information, so let's introduce a single Info struct that collects all the required information in a single place, so that all of these different mechanisms can operate in a more uniform way.
For now, the new info struct is only used to replace a few things:
* The BinderTransactionDataSg struct that is passed as an argument to several methods is removed as the information is moved into the new info struct and passed down that way.
* The oneway spam detection fields on Transaction and Allocation can be removed, as the information can be returned to the caller via the mutable info struct instead.
But several other uses of the info struct are planned in follow-up patches.
--- drivers/android/binder/allocation.rs | 3 - drivers/android/binder/error.rs | 10 +- drivers/android/binder/process.rs | 15 +- drivers/android/binder/thread.rs | 190 +++++++++++++++----------- drivers/android/binder/transaction.rs | 83 ++++++----- rust/kernel/uaccess.rs | 3 + 6 files changed, 170 insertions(+), 134 deletions(-)
drivers/android/binder/allocation.rs +0 -3
@@ -56,7 +56,6 @@ pub(crate) struct Allocation { pub(crate) process: Arc<Process>, allocation_info: Option<AllocationInfo>, free_on_drop: bool, - pub(crate) oneway_spam_detected: bool,#[allow(dead_code)] pub(crate) debug_id: usize, }
@@ -68,7 +67,6 @@ pub(crate) fn new( offset: usize, size: usize, ptr: usize, - oneway_spam_detected: bool, ) -> Self { Self { process,
@@ -76,7 +74,6 @@ pub(crate) fn new( size, ptr, debug_id, - oneway_spam_detected, allocation_info: None, free_on_drop: true, }
drivers/android/binder/error.rs +1 -9
@@ -12,7 +12,7 @@/// errno. pub (crate )struct BinderError {pub (crate ) reply:u32 , - source:Option <Error >, +pub (crate ) source:Option <Error >, }impl BinderError {
@@ -40,14 +40,6 @@ pub(crate) fn new_frozen_oneway() -> Self {pub (crate )fn is_dead (&self) ->bool { self.reply ==BR_DEAD_REPLY } - -pub (crate )fn as_errno (&self) -> kernel::ffi::c_int { - self.source.unwrap_or (EINVAL ).to_errno () - } - -pub (crate )fn should_pr_warn (&self) ->bool { - self.source.is_some () - } }/// Convert an errno into a `BinderError` and store the errno used to construct it. The errno
drivers/android/binder/process.rs +7 -8
@@ -47,6 +47,7 @@ range_alloc::{RangeAllocator, ReserveNew, ReserveNewArgs}, stats::BinderStats, thread::{PushWorkRes, Thread}, + transaction::TransactionInfo, BinderfsProcFile, DArc, DLArc, DTRWrap, DeliverToRead, };
@@ -967,16 +968,15 @@ pub(crate) fn buffer_alloc( self: &Arc<Self>, debug_id: usize, size: usize, - is_oneway: bool, - from_pid: i32, + info: &mut TransactionInfo, ) -> BinderResult<NewAllocation> {use kernel::page::PAGE_SIZE ;let mut reserve_new_args =ReserveNewArgs { debug_id, size, - is_oneway, - pid: from_pid, + is_oneway: info.is_oneway (), + pid: info.from_pid, ..ReserveNewArgs ::default () };
@@ -992,13 +992,13 @@ pub(crate) fn buffer_alloc( reserve_new_args = alloc_request.make_alloc ()?; }; + info.oneway_spam_suspect = new_alloc.oneway_spam_detected;let res =Allocation ::new ( self.clone (), debug_id, new_alloc.offset, size, addr + new_alloc.offset, - new_alloc.oneway_spam_detected, );// This allocation will be marked as in use until the `Allocation` is used to free it.
@@ -1030,7 +1030,7 @@ pub(crate) fn buffer_get(self: &Arc<Self>, ptr: usize) -> Option<Allocation> {let mapping = inner.mapping.as_mut ()?;let offset = ptr.checked_sub (mapping.address)?;let (size, debug_id, odata) = mapping.alloc.reserve_existing (offset).ok ()?; -let mut alloc =Allocation ::new (self.clone (), debug_id, offset, size, ptr,false ); +let mut alloc =Allocation ::new (self.clone (), debug_id, offset, size, ptr);if let Some (data) = odata { alloc.set_info (data); }
@@ -1383,8 +1383,7 @@ fn deferred_release(self: Arc<Self>) { .alloc .take_for_each (|offset, size, debug_id, odata| {let ptr = offset + address; -let mut alloc = -Allocation ::new (self.clone (), debug_id, offset, size, ptr,false ); +let mut alloc =Allocation ::new (self.clone (), debug_id, offset, size, ptr);if let Some (data) = odata { alloc.set_info (data); }
drivers/android/binder/thread.rs +107 -83
290 lines not on this page · raw message
drivers/android/binder/transaction.rs +52 -31
168 lines not on this page · raw message
rust/kernel/uaccess.rs +3 -0
@@ -21,6 +21,9 @@#[derive( Copy , Clone )] pub struct UserPtr (*mut c_void ); +// SAFETY: Null pointer is a valid value. +unsafe impl Zeroable for UserPtr {} +impl UserPtr {/// Create a `UserPtr` from an integer representing the userspace address. #[inline]
Signature · 1 line
2.55.0.795.g602f6c329a-goog
Alice Ryhl
maintainerPATCH 2/2 rust_binder: fix BINDER_GET_EXTENDED_ERROR
This code currently copies the ExtendedError struct to the stack, modifies the copy, and then doesn't modify the original. Thus, fix it.
Furthermore, errors when replying must be delivered directly to the remote thread, so update deliver_reply() to take an extended error argument.
--- drivers/android/binder/error.rs | 13 +++--- drivers/android/binder/thread.rs | 65 +++++++++++++++++++-------- drivers/android/binder/transaction.rs | 15 +++---- 3 files changed, 58 insertions(+), 35 deletions(-)
drivers/android/binder/error.rs +5 -8
@@ -72,20 +72,17 @@ impl core::fmt::Debug for BinderError {fn fmt (&self, f: &mut core::fmt::Formatter <'_>) -> core::fmt::Result {match self.reply {BR_FAILED_REPLY =>match self.source.as_ref () { -Some (source) => f - .debug_struct ("BR_FAILED_REPLY" ) - .field ("source" , source) - .finish (), +Some (source) => source.fmt (f),None => f.pad ("BR_FAILED_REPLY" ), },BR_DEAD_REPLY => f.pad ("BR_DEAD_REPLY" ),BR_FROZEN_REPLY => f.pad ("BR_FROZEN_REPLY" ),BR_TRANSACTION_PENDING_FROZEN => f.pad ("BR_TRANSACTION_PENDING_FROZEN" ),BR_TRANSACTION_COMPLETE => f.pad ("BR_TRANSACTION_COMPLETE" ), - _ => f - .debug_struct ("BinderError" ) - .field ("reply" , &self.reply) - .finish (), + _ =>match self.source.as_ref () { +Some (source) => source.fmt (f), +None => self.reply.fmt (f), + }, } } }
drivers/android/binder/thread.rs +46 -19
135 lines not on this page · raw message
drivers/android/binder/transaction.rs +7 -8
@@ -42,6 +42,7 @@ pub(crate) struct TransactionInfo { pub(crate) reply: u32, pub(crate) oneway_spam_suspect: bool, pub(crate) is_reply: bool, + pub(crate) debug_id: usize, }impl TransactionInfo {
@@ -82,7 +83,6 @@ pub(crate) fn new( from: &Arc<Thread>, info: &mut TransactionInfo, ) -> BinderResult<DLArc<Self>> { -let debug_id =super ::next_debug_id ();let allow_fds = node_ref.node.flags &FLAT_BINDER_FLAG_ACCEPTS_FDS !=0 ;let txn_security_ctx = node_ref.node.flags &FLAT_BINDER_FLAG_TXN_SECURITY_CTX !=0 ;let mut txn_security_ctx_off =if txn_security_ctx {Some (0 ) }else {None };
@@ -90,7 +90,7 @@ pub(crate) fn new(let mut alloc =match from.copy_transaction_data ( to.clone (), info, - debug_id, + info.debug_id, allow_fds, txn_security_ctx_off.as_mut (), ) {
@@ -117,7 +117,7 @@ pub(crate) fn new(let data_address = alloc.ptr; Ok(DTRWrap::arc_pin_init(pin_init!(Transaction { - debug_id, + debug_id: info.debug_id, target_node: Some(target_node), from_parent, sender_euid: from.process.task.euid(),
@@ -141,9 +141,8 @@ pub(crate) fn new_reply( info: &mut TransactionInfo, allow_fds: bool, ) -> BinderResult<DLArc<Self>> { -let debug_id =super ::next_debug_id ();let mut alloc = -match from.copy_transaction_data (to.clone (), info, debug_id, allow_fds,None ) { +match from.copy_transaction_data (to.clone (), info, info.debug_id, allow_fds,None ) {Ok (alloc) => alloc,Err (err) => {pr_warn! ("Failure in copy_transaction_data: {:?}" , err);
@@ -154,7 +153,7 @@ pub(crate) fn new_reply( alloc.set_info_clear_on_drop (); } Ok(DTRWrap::arc_pin_init(pin_init!(Transaction { - debug_id, + debug_id: info.debug_id, target_node: None, from_parent: None, sender_euid: from.process.task.euid(),
@@ -380,7 +379,7 @@ fn do_work(let send_failed_reply =ScopeGuard ::new (|| {if self.target_node.is_some () && self.flags &TF_ONE_WAY ==0 {let reply =Err (BR_FAILED_REPLY ); - self.from.deliver_reply (reply, &self); + self.from.deliver_reply (reply, &self,None ); } self.drop_outstanding_txn (); });
@@ -462,7 +461,7 @@ fn cancel(self: DArc<Self>) {// If this is not a reply or oneway transaction, then send a dead reply. if self.target_node.is_some () && self.flags &TF_ONE_WAY ==0 {let reply =Err (BR_DEAD_REPLY ); - self.from.deliver_reply (reply, &self); + self.from.deliver_reply (reply, &self,None ); } self.drop_outstanding_txn ();
Signature · 1 line
2.55.0.795.g602f6c329a-goog
Re: [PATCH 6.18.y 1/2] rust_binder: introduce TransactionInfo
In reply to Alice RyhlQuoted 3 lines
Rust Binder exposes information about transactions that are sent in various ways: printing to the kernel log, tracepoints, files in binderfs, and the upcoming netlink support.
Queued the series for 6.18, thanks.
Signature · 2 lines
Thanks, Sasha