summaryrefslogtreecommitdiff
path: root/drivers/android
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/android')
-rw-r--r--drivers/android/binder/error.rs4
-rw-r--r--drivers/android/binder/thread.rs78
-rw-r--r--drivers/android/binder/transaction.rs28
3 files changed, 43 insertions, 67 deletions
diff --git a/drivers/android/binder/error.rs b/drivers/android/binder/error.rs
index 41b07d687b30..89077c5baeaf 100644
--- a/drivers/android/binder/error.rs
+++ b/drivers/android/binder/error.rs
@@ -71,10 +71,6 @@ impl BinderError {
line: ErrorLocation::caller(),
}
}
-
- pub(crate) fn is_dead(&self) -> bool {
- self.reply == BR_DEAD_REPLY
- }
}
/// Convert an errno into a `BinderError` and store the errno used to construct it. The errno
diff --git a/drivers/android/binder/thread.rs b/drivers/android/binder/thread.rs
index 0e832af484ce..4b67d58406b6 100644
--- a/drivers/android/binder/thread.rs
+++ b/drivers/android/binder/thread.rs
@@ -1071,17 +1071,7 @@ impl Thread {
size_of::<u64>(),
);
let secctx_off = aligned_data_size + offsets_size + buffers_size;
- let mut alloc = match to_process.buffer_alloc(debug_id, len, info) {
- Ok(alloc) => alloc,
- Err(err) => {
- pr_warn!(
- "Failed to allocate buffer. len:{}, is_oneway:{}",
- len,
- info.is_oneway(),
- );
- return Err(err);
- }
- };
+ let mut alloc = to_process.buffer_alloc(debug_id, len, info)?;
trace_transaction_alloc_buf(debug_id, data_size, offsets_size, buffers_size);
@@ -1334,38 +1324,19 @@ impl Thread {
self.transaction_inner(&mut info)
};
+ // This runs when return work is passed to the caller. This is not
+ // always the same as the transaction failing, as reply errors are
+ // delivered to the remote process.
if let Err(err) = ret {
self.push_return_work(err.reply);
if err.reply != BR_TRANSACTION_COMPLETE {
info.reply = err.reply;
info.error_line = Some(err.line);
- if let Some(source) = &err.source {
- info.errno = source.to_errno();
-
- {
- let mut inner = self.inner.lock();
- inner.extended_error =
- ExtendedError::new(info.debug_id as u32, err.reply, source.to_errno());
- }
+ if let Some(source) = err.source {
+ info.errno = Some(source);
- binder_debug!(
- FailedTransaction,
- "transaction {} to {}:{} failed {:?}, code {} size {}-{} line {}",
- if info.is_reply {
- "reply"
- } else if info.is_oneway() {
- "async"
- } else {
- "call"
- },
- info.to_pid,
- info.to_tid,
- err,
- info.code,
- info.data_size,
- info.offsets_size,
- err.line
- );
+ self.inner.lock().extended_error =
+ ExtendedError::new(info.debug_id as u32, err.reply, source.to_errno());
}
}
}
@@ -1377,8 +1348,33 @@ impl Thread {
// useful in case the transaction failed with BR_TRANSACTION_PENDING_FROZEN.
info.report_netlink(BR_ONEWAY_SPAM_SUSPECT, &self.process.ctx);
}
+ // This runs when the transaction failed.
if info.reply != 0 {
info.report_netlink(info.reply, &self.process.ctx);
+ if let Some(errno) = info.errno {
+ let error_line: &dyn kernel::fmt::Display = match &info.error_line {
+ Some(line) => line,
+ None => &0,
+ };
+ binder_debug!(
+ FailedTransaction,
+ "transaction {} to {}:{} failed {:?}, code {} size {}-{} line {}",
+ if info.is_reply {
+ "reply"
+ } else if info.is_oneway() {
+ "async"
+ } else {
+ "call"
+ },
+ info.to_pid,
+ info.to_tid,
+ errno,
+ info.code,
+ info.data_size,
+ info.offsets_size,
+ error_line
+ );
+ }
}
Ok(())
@@ -1471,18 +1467,12 @@ impl Thread {
// At this point we only return `BR_TRANSACTION_COMPLETE` to the caller, and we must let
// the sender know that the transaction has completed (with an error in this case).
- pr_warn!(
- "{}:{} reply to {} failed: {err:?}",
- info.from_pid,
- info.from_tid,
- info.to_pid
- );
let param = err.source.as_ref().map_or(0, |e| e.to_errno());
let ee = ExtendedError::new(info.debug_id as u32, err.reply, param);
orig.from
.deliver_reply(Err(BR_FAILED_REPLY), &orig, Some(ee));
info.reply = BR_FAILED_REPLY;
- info.errno = param;
+ info.errno = err.source;
info.error_line = Some(err.line);
err.reply = BR_TRANSACTION_COMPLETE;
err
diff --git a/drivers/android/binder/transaction.rs b/drivers/android/binder/transaction.rs
index 7b8df44aa1c3..48ac942bb75a 100644
--- a/drivers/android/binder/transaction.rs
+++ b/drivers/android/binder/transaction.rs
@@ -136,7 +136,11 @@ impl TransactionLogEntry {
offsets_size: info.offsets_size,
return_error_line: if failed { info.error_line } else { None },
return_error: if failed { info.reply } else { 0 },
- return_error_param: if failed { info.errno } else { 0 },
+ return_error_param: if failed {
+ info.errno.map_or(0, |e| e.to_errno())
+ } else {
+ 0
+ },
context_name,
}
}
@@ -254,7 +258,7 @@ pub(crate) struct TransactionInfo {
pub(crate) offsets_size: usize,
pub(crate) buffers_size: usize,
pub(crate) target_handle: u32,
- pub(crate) errno: i32,
+ pub(crate) errno: Option<Error>,
pub(crate) reply: u32,
pub(crate) error_line: Option<ErrorLocation>,
pub(crate) oneway_spam_suspect: bool,
@@ -361,21 +365,13 @@ impl Transaction {
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 };
let to = node_ref.node.owner.clone();
- let mut alloc = match from.copy_transaction_data(
+ let mut alloc = from.copy_transaction_data(
to.clone(),
info,
info.debug_id,
allow_fds,
txn_security_ctx_off.as_mut(),
- ) {
- Ok(alloc) => alloc,
- Err(err) => {
- if !err.is_dead() {
- pr_warn!("Failure in copy_transaction_data: {:?}", err);
- }
- return Err(err);
- }
- };
+ )?;
if info.is_oneway() {
if from_parent.is_some() {
pr_warn_ratelimited!("Oneway transaction should not be in a transaction stack.\n");
@@ -416,13 +412,7 @@ impl Transaction {
allow_fds: bool,
) -> BinderResult<DLArc<Self>> {
let mut alloc =
- 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);
- return Err(err);
- }
- };
+ from.copy_transaction_data(to.clone(), info, info.debug_id, allow_fds, None)?;
if info.flags.contains(TransactionFlag::ClearBuf) {
alloc.set_info_clear_on_drop();
}