From nobody Mon Jun 8 06:36:15 2026 Received: from mail-wm1-f73.google.com (mail-wm1-f73.google.com [209.85.128.73]) (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 9904F3ED5DC for ; Fri, 5 Jun 2026 11:13:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780658041; cv=none; b=eaIOyr5DKO6AsLX4HJGuD6WqGS5cQaXtjt9YFxVZShaUPxtCvbe5euViVvQcBUkupi+GwQIrlj7/qkIhqHJzJLrW8EU019LTvnTWExtSofGb2vfARjX0aETjgQgoZ7CO/Q9TnZa2a8tR2dYgboBhuTUP9kg9LONV1H2K1nqPBG8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1780658041; c=relaxed/simple; bh=pE3Md5fXo59d3VmXaqKfkEFBwkt/gMYRvtNwlnkDoGw=; h=Date:Mime-Version:Message-ID:Subject:From:To:Cc:Content-Type; b=A4+yCHXP+Q3yswX+6iUszMNNf3oySzjJtJTkLORZW8zfDJAFzKlMWmXN3mR/8OQGVwbfA5pDkbS74SRT8So0bbMSVe1UYkbrFz4RvDw0/E5Eb5q6WBhbjCHeFs2tFZ7/l6AjQdmk92dkUdLtVxicEUAFVG5pFi0H0pBN25XJE48= 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=TJcOiDBi; arc=none smtp.client-ip=209.85.128.73 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="TJcOiDBi" Received: by mail-wm1-f73.google.com with SMTP id 5b1f17b1804b1-490a767c7dcso15419985e9.2 for ; Fri, 05 Jun 2026 04:13:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20251104; t=1780658038; x=1781262838; darn=vger.kernel.org; h=cc:to:from:subject:message-id:mime-version:date:from:to:cc:subject :date:message-id:reply-to; bh=Ae0B3L9J3p8ch5V1iNM9m91ribQPpzMSLrk2/8ZfsoU=; b=TJcOiDBiI7pc4ZXvq3Vxwn0YaBYUcfYybdl6AiTwaWTUrgdmtAgZB0tB4fK1um3CCB nePEMJDIppnFooZ9qL6zKujDlA5E+fI5VXRtFqV9wlzTgiq8us+qnlfIByGN+5G5guGZ eXJpN4fx5uRkkZlQbXK47QU4Up/GmYJQIwK87jvdRYY0g1vmrkNm8xqj4KgTGZkdejgU fSUb1y4xaiHJaZt2SvFA+WNopya6LJIgIVYDwaaL2EcPQ2pYE9d+osK4TOKmcxolmD/R CRJAnM1+DsCAwk3LuzZHrR7Cj0i/lf9Jiiwr2D+7/3tpXzOSl+BAuSaFdlNGIedZ1BUn 7X+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1780658038; x=1781262838; h=cc:to:from:subject:message-id:mime-version:date:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=Ae0B3L9J3p8ch5V1iNM9m91ribQPpzMSLrk2/8ZfsoU=; b=k5oHbPPVgatVQ/HqF/sJqaKqlB1nnScViIchOpWNV/rwTYgGA0L7gPnir4k17AZxNF NcS7sHkXEchQWjTL1s1TfYseaSW9zNar8LRzBsFDPdnFYcewLOoeTlBra6DK1qTDS/Du psTS7GBdyFlVWG737ms/KohmKSWjpUGxMbzm8QopnsAhDXxv98KS0UYe1re3DDrNmctz bp4BL0JU8AKdVOiqyN3d6PPDZpC+8b6k32sHhMbApGSqToQhL80NK0SN2GEdNIAgB7hl /eSKcgWf2CbXHGAXHUsYgZR31vbd5HR2bwNFeiuJ2oigNcvaSZTyscgA2lZpj2YWEQ8n q3Sg== X-Forwarded-Encrypted: i=1; AFNElJ88Sz9nSH9hujzyxEgjlBcrEsvzlOiXKJXz+ULUIR2Boq0ywb6qPEpwaSRI15NgJgGfG4Oz2z8jl3MTRpY=@vger.kernel.org X-Gm-Message-State: AOJu0YxGGBvoFNF3uKKO9thlm6G2oNHMaBjPgS85IBvrEGe7TuB38Hdw b80XuXT3yokjQCdH/ai6BFJo9Iem/E7olBJDF0+Zy4ZnMyi3/nJu0EbMKffz7d5uYHXeJzagazY In8Z5s1/400QF1Rg4ZQ== X-Received: from wmok21.prod.google.com ([2002:a05:600c:4795:b0:490:bae0:2975]) (user=aliceryhl job=prod-delivery.src-stubby-dispatcher) by 2002:a05:600c:1f83:b0:490:b724:5085 with SMTP id 5b1f17b1804b1-490c2621a5cmr47158285e9.33.1780658037867; Fri, 05 Jun 2026 04:13:57 -0700 (PDT) Date: Fri, 05 Jun 2026 11:13:50 +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=H4sIAG6vImoC/33NTQrCMBCG4auUrI1M84uuvIe4aJppG9BGJiVUS u9u2o0I4vL9YJ5ZWEIKmNi5WhhhDinEsYQ8VKwdmrFHHnxpJkAY0MLyhBPHecLRo+dIFImjaBt pEczJeFYOn4RdmHf0eis9hDRFeu0/cr2tf7lc85orsE45ZQxIfelj7O94bOODbV4WH8OA+mmIY nQOrJZoG6fll7Gu6xuXk4Qp+QAAAA== X-Change-Id: 20260527-set-extended-error-e2ca37e0696d X-Developer-Key: i=aliceryhl@google.com; a=openpgp; fpr=49F6C1FAA74960F43A5B86A1EE7A392FDE96209F X-Developer-Signature: v=1; a=openpgp-sha256; l=11911; i=aliceryhl@google.com; h=from:subject:message-id; bh=pE3Md5fXo59d3VmXaqKfkEFBwkt/gMYRvtNwlnkDoGw=; b=owEBbQKS/ZANAwAKAQRYvu5YxjlGAcsmYgBqIq9wU6XpkHkwl3E14lJQ7fDDs3KlybRbe9UYK o9fdlp5/RWJAjMEAAEKAB0WIQSDkqKUTWQHCvFIvbIEWL7uWMY5RgUCaiKvcAAKCRAEWL7uWMY5 RoW2D/93a9/E36XsCLJvlujc9bRkSuTj10LyqNY5CJj6OEe/nRF0x+Rf+46BavmlqvTzTOC7hfZ tqW/VAyp0vuPaRd7NkK3CDsx0zCCh6w2YSPlolFbUSjUKgt8x5whb3TKo6tpxvEeji6ctosMHE1 CmI0DwveK44+Nu4t67OiSvleRceTaENQAY0zP28uRHAkAGx3RhYiJnOk0JePCaGP5Fz95Dwkvd6 Bj1QgAYD5Rj2UrAckiwKYZss46mxhNuDWmf3tI4kZKzmZ2aSlxH1ZNL96L/BYhRE8/ZfrNqbbCY NjC98shSHP+BpCq1RR3IxHy7idMfdzK3IzaiEkrBw02wyCJt0T3RQ8Gch2PZe8yFlK6ZRcPPwQ7 /cXS8uQf2I07yXA8GrZSyq+Vcdck/i0oqqAry4J6a3Z9JwHP8QW6fBs6AlUCP7J9cyimQ49vm9b /0NfSFCfF+Zvd9FyRUW3c0HHyn7XlbVM1shkljfl82s0bFZebEWGSiAr0JCXyO8qFbotQbzwn4f I9YZOGhFrAAM85hr+oLkAAF8erxZfz4TQYS4J4xGIl/9IdnUJIXCfUCVtw7qt/ya+2+9CLp2nf6 WoE/OWRatEoc9LbxT88h2MuvH/L3qxL3HJa4D4JjruWfWnNLic8sV04gjYVvJi2dESq1GvTqJRO 6HvZ8MUY5ZRvbbw== X-Mailer: b4 0.14.3 Message-ID: <20260605-set-extended-error-v3-1-d60b69a75f97@google.com> Subject: [PATCH v3] rust_binder: fix BINDER_GET_EXTENDED_ERROR 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" Content-Transfer-Encoding: quoted-printable 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. Cc: stable@vger.kernel.org Fixes: eafedbc7c050 ("rust_binder: add Rust Binder driver") Signed-off-by: Alice Ryhl Acked-by: Carlos Llamas --- Changes in v3: - Replace 'orig.debug_id' with 'info.debug_id' for reply EE. - Print the integer error code on unknown error. - Link to v2: https://lore.kernel.org/r/20260604-set-extended-error-v2-1-fb= 0753e7ab53@google.com Changes in v2: - Also handle extended error for replies. - Link to v1: https://lore.kernel.org/r/20260527-set-extended-error-v1-1-40= 7b4b466035@google.com --- 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(-) diff --git a/drivers/android/binder/error.rs b/drivers/android/binder/error= .rs index 45d85d4c2815..1296072c35d9 100644 --- a/drivers/android/binder/error.rs +++ b/drivers/android/binder/error.rs @@ -73,20 +73,17 @@ impl fmt::Debug for BinderError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self.reply { BR_FAILED_REPLY =3D> match self.source.as_ref() { - Some(source) =3D> f - .debug_struct("BR_FAILED_REPLY") - .field("source", source) - .finish(), + Some(source) =3D> source.fmt(f), None =3D> f.pad("BR_FAILED_REPLY"), }, BR_DEAD_REPLY =3D> f.pad("BR_DEAD_REPLY"), BR_FROZEN_REPLY =3D> f.pad("BR_FROZEN_REPLY"), BR_TRANSACTION_PENDING_FROZEN =3D> f.pad("BR_TRANSACTION_PENDI= NG_FROZEN"), BR_TRANSACTION_COMPLETE =3D> f.pad("BR_TRANSACTION_COMPLETE"), - _ =3D> f - .debug_struct("BinderError") - .field("reply", &self.reply) - .finish(), + _ =3D> match self.source.as_ref() { + Some(source) =3D> source.fmt(f), + None =3D> self.reply.fmt(f), + }, } } } diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thre= ad.rs index 97d5f31e8fe3..3b8520813941 100644 --- a/drivers/android/binder/thread.rs +++ b/drivers/android/binder/thread.rs @@ -495,9 +495,16 @@ pub(crate) fn debug_print(self: &Arc, m: &SeqFil= e, print_all: bool) -> Res Ok(()) } =20 + pub(crate) fn clear_extended_error(&self, debug_id: usize) { + self.inner.lock().extended_error =3D ExtendedError::new(debug_id a= s u32, BR_OK, 0); + } + pub(crate) fn get_extended_error(&self, data: UserSlice) -> Result { let mut writer =3D data.writer(); - let ee =3D self.inner.lock().extended_error; + let mut inner =3D self.inner.lock(); + let ee =3D inner.extended_error; + inner.extended_error =3D ExtendedError::new(0, BR_OK, 0); + drop(inner); writer.write(&ee)?; Ok(()) } @@ -1109,7 +1116,10 @@ fn unwind_transaction_stack(self: &Arc) { inner.pop_transaction_to_reply(thread.as_ref()) } { let reply =3D Err(BR_DEAD_REPLY); - if !transaction.from.deliver_single_reply(reply, &transaction)= { + if !transaction + .from + .deliver_single_reply(reply, &transaction, None) + { break; } =20 @@ -1121,8 +1131,9 @@ pub(crate) fn deliver_reply( &self, reply: Result, u32>, transaction: &DArc, + extended_error: Option, ) { - if self.deliver_single_reply(reply, transaction) { + if self.deliver_single_reply(reply, transaction, extended_error) { transaction.from.unwind_transaction_stack(); } } @@ -1136,6 +1147,7 @@ fn deliver_single_reply( &self, reply: Result, u32>, transaction: &DArc, + extended_error: Option, ) -> bool { if let Ok(transaction) =3D &reply { crate::trace::trace_transaction(true, transaction, Some(&self.= task)); @@ -1152,6 +1164,12 @@ fn deliver_single_reply( return true; } =20 + if let Some(ee) =3D extended_error { + if inner.extended_error.command =3D=3D BR_OK { + inner.extended_error =3D ee; + } + } + match reply { Ok(work) =3D> { inner.push_work(work); @@ -1222,6 +1240,9 @@ fn read_transaction_info( info.buffers_size =3D td.buffers_size as usize; // SAFETY: Above `read` call initializes all bytes, so this union = read is ok. info.target_handle =3D unsafe { td.transaction_data.target.handle = }; + + info.debug_id =3D super::next_debug_id(); + Ok(()) } =20 @@ -1230,6 +1251,8 @@ fn transaction(self: &Arc, cmd: u32, reader: &m= ut UserSliceReader) -> Resu let mut info =3D TransactionInfo::zeroed(); self.read_transaction_info(cmd, reader, &mut info)?; =20 + self.clear_extended_error(info.debug_id); + let ret =3D if info.is_reply { self.reply_inner(&mut info) } else if info.is_oneway() { @@ -1239,23 +1262,21 @@ fn transaction(self: &Arc, cmd: u32, reader: = &mut UserSliceReader) -> Resu }; =20 if let Err(err) =3D ret { - if err.reply !=3D BR_TRANSACTION_COMPLETE { - info.reply =3D err.reply; - } - self.push_return_work(err.reply); - if let Some(source) =3D &err.source { - info.errno =3D source.to_errno(); + if err.reply !=3D BR_TRANSACTION_COMPLETE { info.reply =3D err.reply; + if let Some(source) =3D &err.source { + info.errno =3D source.to_errno(); =20 - { - let mut ee =3D self.inner.lock().extended_error; - ee.command =3D err.reply; - ee.param =3D source.to_errno(); + { + let mut inner =3D self.inner.lock(); + inner.extended_error =3D + ExtendedError::new(info.debug_id as u32, err.r= eply, source.to_errno()); + } } =20 pr_warn!( - "{}:{} transaction to {} failed: {source:?}", + "{}:{} transaction to {} failed: {err:?}", info.from_pid, info.from_tid, info.to_pid @@ -1320,18 +1341,24 @@ fn reply_inner(self: &Arc, info: &mut Transac= tionInfo) -> BinderResult { let allow_fds =3D orig.flags & TF_ACCEPT_FDS !=3D 0; let reply =3D Transaction::new_reply(self, process, info, allo= w_fds)?; self.inner.lock().push_work(completion); - orig.from.deliver_reply(Ok(reply), &orig); + orig.from.deliver_reply(Ok(reply), &orig, None); Ok(()) })() .map_err(|mut err| { // At this point we only return `BR_TRANSACTION_COMPLETE` to t= he caller, and we must let // the sender know that the transaction has completed (with an= error in this case). + pr_warn!( - "Failure {:?} during reply - delivering BR_FAILED_REPLY to= sender.", - err + "{}:{} reply to {} failed: {err:?}", + info.from_pid, + info.from_tid, + info.to_pid ); - let reply =3D Err(BR_FAILED_REPLY); - orig.from.deliver_reply(reply, &orig); + + let param =3D err.source.as_ref().map_or(0, |e| e.to_errno()); + let ee =3D ExtendedError::new(info.debug_id as u32, err.reply,= param); + orig.from + .deliver_reply(Err(BR_FAILED_REPLY), &orig, Some(ee)); err.reply =3D BR_TRANSACTION_COMPLETE; err }); diff --git a/drivers/android/binder/transaction.rs b/drivers/android/binder= /transaction.rs index 1d9b66920a21..0e5d07b7e6f0 100644 --- a/drivers/android/binder/transaction.rs +++ b/drivers/android/binder/transaction.rs @@ -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, } =20 impl TransactionInfo { @@ -93,7 +94,6 @@ pub(crate) fn new( from: &Arc, info: &mut TransactionInfo, ) -> BinderResult> { - let debug_id =3D super::next_debug_id(); let allow_fds =3D node_ref.node.flags & FLAT_BINDER_FLAG_ACCEPTS_F= DS !=3D 0; let txn_security_ctx =3D node_ref.node.flags & FLAT_BINDER_FLAG_TX= N_SECURITY_CTX !=3D 0; let mut txn_security_ctx_off =3D if txn_security_ctx { Some(0) } e= lse { None }; @@ -101,7 +101,7 @@ pub(crate) fn new( let mut alloc =3D 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 =3D alloc.ptr; =20 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> { - let debug_id =3D super::next_debug_id(); let mut alloc =3D - match from.copy_transaction_data(to.clone(), info, debug_id, a= llow_fds, None) { + match from.copy_transaction_data(to.clone(), info, info.debug_= id, allow_fds, None) { Ok(alloc) =3D> alloc, Err(err) =3D> { 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 =3D ScopeGuard::new(|| { if self.target_node.is_some() && self.flags & TF_ONE_WAY =3D= =3D 0 { let reply =3D 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) { // 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 =3D=3D 0 { let reply =3D Err(BR_DEAD_REPLY); - self.from.deliver_reply(reply, &self); + self.from.deliver_reply(reply, &self, None); } =20 self.drop_outstanding_txn(); --- base-commit: da61573f783897ae5a96c8f1c71aad6242344feb change-id: 20260527-set-extended-error-e2ca37e0696d Best regards, --=20 Alice Ryhl