Skip to content

Commit b165a6d

Browse files
Carlos LlamasDarksonn
authored andcommitted
rust_binder: report netlink transactions
The Android Binder driver supports a netlink API that reports transaction *failures* to a userapce daemon. This allows devices to monitor processes with many failed transactions so that it can e.g. kill misbehaving apps. One very important thing that this monitors is when many oneway messages are sent to a frozen process, so there is special handling to ensure this scenario is surfaced over netlink. Signed-off-by: Carlos Llamas <[email protected]> Signed-off-by: Alice Ryhl <[email protected]>
1 parent 0aadcd6 commit b165a6d

3 files changed

Lines changed: 49 additions & 1 deletion

File tree

drivers/android/binder/rust_binder_main.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ mod context;
3636
mod deferred_close;
3737
mod defs;
3838
mod error;
39-
#[allow(dead_code)]
4039
mod netlink;
4140
mod node;
4241
mod page_range;

drivers/android/binder/thread.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,6 +1263,15 @@ impl Thread {
12631263
}
12641264
}
12651265

1266+
if info.oneway_spam_suspect {
1267+
// If this is both a oneway spam suspect and a failure, we report it twice. This is
1268+
// useful in case the transaction failed with BR_TRANSACTION_PENDING_FROZEN.
1269+
info.report_netlink(BR_ONEWAY_SPAM_SUSPECT, &self.process.ctx);
1270+
}
1271+
if info.reply != 0 {
1272+
info.report_netlink(info.reply, &self.process.ctx);
1273+
}
1274+
12661275
Ok(())
12671276
}
12681277

drivers/android/binder/transaction.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// Copyright (C) 2025 Google LLC.
44

55
use kernel::{
6+
netlink::GENLMSG_DEFAULT_SIZE,
67
prelude::*,
78
seq_file::SeqFile,
89
seq_print,
@@ -17,6 +18,7 @@ use crate::{
1718
allocation::{Allocation, TranslatedFds},
1819
defs::*,
1920
error::{BinderError, BinderResult},
21+
netlink::Report,
2022
node::{Node, NodeRef},
2123
process::{Process, ProcessInner},
2224
ptr_align,
@@ -49,6 +51,44 @@ impl TransactionInfo {
4951
pub(crate) fn is_oneway(&self) -> bool {
5052
self.flags & TF_ONE_WAY != 0
5153
}
54+
55+
pub(crate) fn report_netlink(&self, reply: u32, ctx: &crate::Context) {
56+
if let Err(err) = self.report_netlink_inner(reply, ctx) {
57+
pr_warn!(
58+
"{}:{} netlink report failed: {err:?}\n",
59+
self.from_pid,
60+
self.from_tid
61+
);
62+
}
63+
}
64+
65+
fn report_netlink_inner(&self, reply: u32, ctx: &crate::Context) -> kernel::error::Result {
66+
if !Report::has_listeners() {
67+
return Ok(());
68+
}
69+
let mut report = Report::new(GENLMSG_DEFAULT_SIZE, 0, 0, GFP_KERNEL)?;
70+
71+
report.error(reply)?;
72+
report.context(&ctx.name)?;
73+
report.from_pid(self.from_pid as u32)?;
74+
report.from_tid(self.from_tid as u32)?;
75+
if self.to_pid != 0 {
76+
report.to_pid(self.to_pid as u32)?;
77+
}
78+
if self.to_tid != 0 {
79+
report.to_tid(self.to_tid as u32)?;
80+
}
81+
82+
if self.is_reply {
83+
report.is_reply()?;
84+
}
85+
report.flags(self.flags)?;
86+
report.code(self.code)?;
87+
report.data_size(self.data_size as u32)?;
88+
89+
report.multicast(0, GFP_KERNEL)?;
90+
Ok(())
91+
}
5292
}
5393

5494
use core::mem::offset_of;

0 commit comments

Comments
 (0)