Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: GPL-2.0
2
3// Copyright (C) 2025 Google LLC.
4
5//! Binder -- the Android IPC mechanism.
6#![recursion_limit = "256"]
7#![allow(
8 clippy::as_underscore,
9 clippy::ref_as_ptr,
10 clippy::ptr_as_ptr,
11 clippy::cast_lossless
12)]
13
14use kernel::{
15 bindings::{self, seq_file},
16 fs::File,
17 list::{ListArc, ListArcSafe, ListLinksSelfPtr, TryNewListArc},
18 prelude::*,
19 seq_file::SeqFile,
20 seq_print,
21 sync::poll::PollTable,
22 sync::Arc,
23 task::Pid,
24 transmute::AsBytes,
25 types::ForeignOwnable,
26 uaccess::UserSliceWriter,
27};
28
29use crate::{context::Context, page_range::Shrinker, process::Process, thread::Thread};
30
31use core::{
32 ptr::NonNull,
33 sync::atomic::{AtomicBool, AtomicUsize, Ordering},
34};
35
36mod allocation;
37mod context;
38mod deferred_close;
39mod defs;
40mod error;
41mod node;
42mod page_range;
43mod process;
44mod range_alloc;
45mod stats;
46mod thread;
47mod trace;
48mod transaction;
49
50#[allow(warnings)] // generated bindgen code
51mod binderfs {
52 use kernel::bindings::{dentry, inode};
53
54 extern "C" {
55 pub fn init_rust_binderfs() -> kernel::ffi::c_int;
56 }
57 extern "C" {
58 pub fn rust_binderfs_create_proc_file(
59 nodp: *mut inode,
60 pid: kernel::ffi::c_int,
61 ) -> *mut dentry;
62 }
63 extern "C" {
64 pub fn rust_binderfs_remove_file(dentry: *mut dentry);
65 }
66 pub type rust_binder_context = *mut kernel::ffi::c_void;
67 #[repr(C)]
68 #[derive(Copy, Clone)]
69 pub struct binder_device {
70 pub minor: kernel::ffi::c_int,
71 pub ctx: rust_binder_context,
72 }
73 impl Default for binder_device {
74 fn default() -> Self {
75 let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
76 unsafe {
77 ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
78 s.assume_init()
79 }
80 }
81 }
82}
83
84module! {
85 type: BinderModule,
86 name: "rust_binder",
87 authors: ["Wedson Almeida Filho", "Alice Ryhl"],
88 description: "Android Binder",
89 license: "GPL",
90}
91
92fn next_debug_id() -> usize {
93 static NEXT_DEBUG_ID: AtomicUsize = AtomicUsize::new(0);
94
95 NEXT_DEBUG_ID.fetch_add(1, Ordering::Relaxed)
96}
97
98/// Provides a single place to write Binder return values via the
99/// supplied `UserSliceWriter`.
100pub(crate) struct BinderReturnWriter<'a> {
101 writer: UserSliceWriter,
102 thread: &'a Thread,
103}
104
105impl<'a> BinderReturnWriter<'a> {
106 fn new(writer: UserSliceWriter, thread: &'a Thread) -> Self {
107 BinderReturnWriter { writer, thread }
108 }
109
110 /// Write a return code back to user space.
111 /// Should be a `BR_` constant from [`defs`] e.g. [`defs::BR_TRANSACTION_COMPLETE`].
112 fn write_code(&mut self, code: u32) -> Result {
113 stats::GLOBAL_STATS.inc_br(code);
114 self.thread.process.stats.inc_br(code);
115 self.writer.write(&code)
116 }
117
118 /// Write something *other than* a return code to user space.
119 fn write_payload<T: AsBytes>(&mut self, payload: &T) -> Result {
120 self.writer.write(payload)
121 }
122
123 fn len(&self) -> usize {
124 self.writer.len()
125 }
126}
127
128/// Specifies how a type should be delivered to the read part of a BINDER_WRITE_READ ioctl.
129///
130/// When a value is pushed to the todo list for a process or thread, it is stored as a trait object
131/// with the type `Arc<dyn DeliverToRead>`. Trait objects are a Rust feature that lets you
132/// implement dynamic dispatch over many different types. This lets us store many different types
133/// in the todo list.
134trait DeliverToRead: ListArcSafe + Send + Sync {
135 /// Performs work. Returns true if remaining work items in the queue should be processed
136 /// immediately, or false if it should return to caller before processing additional work
137 /// items.
138 fn do_work(
139 self: DArc<Self>,
140 thread: &Thread,
141 writer: &mut BinderReturnWriter<'_>,
142 ) -> Result<bool>;
143
144 /// Cancels the given work item. This is called instead of [`DeliverToRead::do_work`] when work
145 /// won't be delivered.
146 fn cancel(self: DArc<Self>);
147
148 /// Should we use `wake_up_interruptible_sync` or `wake_up_interruptible` when scheduling this
149 /// work item?
150 ///
151 /// Generally only set to true for non-oneway transactions.
152 fn should_sync_wakeup(&self) -> bool;
153
154 fn debug_print(&self, m: &SeqFile, prefix: &str, transaction_prefix: &str) -> Result<()>;
155}
156
157// Wrapper around a `DeliverToRead` with linked list links.
158#[pin_data]
159struct DTRWrap<T: ?Sized> {
160 #[pin]
161 links: ListLinksSelfPtr<DTRWrap<dyn DeliverToRead>>,
162 #[pin]
163 wrapped: T,
164}
165kernel::list::impl_list_arc_safe! {
166 impl{T: ListArcSafe + ?Sized} ListArcSafe<0> for DTRWrap<T> {
167 tracked_by wrapped: T;
168 }
169}
170kernel::list::impl_list_item! {
171 impl ListItem<0> for DTRWrap<dyn DeliverToRead> {
172 using ListLinksSelfPtr { self.links };
173 }
174}
175
176impl<T: ?Sized> core::ops::Deref for DTRWrap<T> {
177 type Target = T;
178 fn deref(&self) -> &T {
179 &self.wrapped
180 }
181}
182
183type DArc<T> = kernel::sync::Arc<DTRWrap<T>>;
184type DLArc<T> = kernel::list::ListArc<DTRWrap<T>>;
185
186impl<T: ListArcSafe> DTRWrap<T> {
187 fn new(val: impl PinInit<T>) -> impl PinInit<Self> {
188 pin_init!(Self {
189 links <- ListLinksSelfPtr::new(),
190 wrapped <- val,
191 })
192 }
193
194 fn arc_try_new(val: T) -> Result<DLArc<T>, kernel::alloc::AllocError> {
195 ListArc::pin_init(
196 try_pin_init!(Self {
197 links <- ListLinksSelfPtr::new(),
198 wrapped: val,
199 }),
200 GFP_KERNEL,
201 )
202 .map_err(|_| kernel::alloc::AllocError)
203 }
204
205 fn arc_pin_init(init: impl PinInit<T>) -> Result<DLArc<T>, kernel::error::Error> {
206 ListArc::pin_init(
207 try_pin_init!(Self {
208 links <- ListLinksSelfPtr::new(),
209 wrapped <- init,
210 }),
211 GFP_KERNEL,
212 )
213 }
214}
215
216struct DeliverCode {
217 code: u32,
218 skip: AtomicBool,
219}
220
221kernel::list::impl_list_arc_safe! {
222 impl ListArcSafe<0> for DeliverCode { untracked; }
223}
224
225impl DeliverCode {
226 fn new(code: u32) -> Self {
227 Self {
228 code,
229 skip: AtomicBool::new(false),
230 }
231 }
232
233 /// Disable this DeliverCode and make it do nothing.
234 ///
235 /// This is used instead of removing it from the work list, since `LinkedList::remove` is
236 /// unsafe, whereas this method is not.
237 fn skip(&self) {
238 self.skip.store(true, Ordering::Relaxed);
239 }
240}
241
242impl DeliverToRead for DeliverCode {
243 fn do_work(
244 self: DArc<Self>,
245 _thread: &Thread,
246 writer: &mut BinderReturnWriter<'_>,
247 ) -> Result<bool> {
248 if !self.skip.load(Ordering::Relaxed) {
249 writer.write_code(self.code)?;
250 }
251 Ok(true)
252 }
253
254 fn cancel(self: DArc<Self>) {}
255
256 fn should_sync_wakeup(&self) -> bool {
257 false
258 }
259
260 fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> {
261 seq_print!(m, "{}", prefix);
262 if self.skip.load(Ordering::Relaxed) {
263 seq_print!(m, "(skipped) ");
264 }
265 if self.code == defs::BR_TRANSACTION_COMPLETE {
266 seq_print!(m, "transaction complete\n");
267 } else {
268 seq_print!(m, "transaction error: {}\n", self.code);
269 }
270 Ok(())
271 }
272}
273
274fn ptr_align(value: usize) -> Option<usize> {
275 let size = core::mem::size_of::<usize>() - 1;
276 Some(value.checked_add(size)? & !size)
277}
278
279// SAFETY: We call register in `init`.
280static BINDER_SHRINKER: Shrinker = unsafe { Shrinker::new() };
281
282struct BinderModule {}
283
284impl kernel::Module for BinderModule {
285 fn init(_module: &'static kernel::ThisModule) -> Result<Self> {
286 // SAFETY: The module initializer never runs twice, so we only call this once.
287 unsafe { crate::context::CONTEXTS.init() };
288
289 pr_warn!("Loaded Rust Binder.");
290
291 BINDER_SHRINKER.register(kernel::c_str!("android-binder"))?;
292
293 // SAFETY: The module is being loaded, so we can initialize binderfs.
294 unsafe { kernel::error::to_result(binderfs::init_rust_binderfs())? };
295
296 Ok(Self {})
297 }
298}
299
300/// Makes the inner type Sync.
301#[repr(transparent)]
302pub struct AssertSync<T>(T);
303// SAFETY: Used only to insert `file_operations` into a global, which is safe.
304unsafe impl<T> Sync for AssertSync<T> {}
305
306/// File operations that rust_binderfs.c can use.
307#[no_mangle]
308#[used]
309pub static rust_binder_fops: AssertSync<kernel::bindings::file_operations> = {
310 // SAFETY: All zeroes is safe for the `file_operations` type.
311 let zeroed_ops = unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
312
313 let ops = kernel::bindings::file_operations {
314 owner: THIS_MODULE.as_ptr(),
315 poll: Some(rust_binder_poll),
316 unlocked_ioctl: Some(rust_binder_ioctl),
317 compat_ioctl: Some(bindings::compat_ptr_ioctl),
318 mmap: Some(rust_binder_mmap),
319 open: Some(rust_binder_open),
320 release: Some(rust_binder_release),
321 flush: Some(rust_binder_flush),
322 ..zeroed_ops
323 };
324 AssertSync(ops)
325};
326
327/// # Safety
328/// Only called by binderfs.
329#[no_mangle]
330unsafe extern "C" fn rust_binder_new_context(
331 name: *const kernel::ffi::c_char,
332) -> *mut kernel::ffi::c_void {
333 // SAFETY: The caller will always provide a valid c string here.
334 let name = unsafe { kernel::str::CStr::from_char_ptr(name) };
335 match Context::new(name) {
336 Ok(ctx) => Arc::into_foreign(ctx),
337 Err(_err) => core::ptr::null_mut(),
338 }
339}
340
341/// # Safety
342/// Only called by binderfs.
343#[no_mangle]
344unsafe extern "C" fn rust_binder_remove_context(device: *mut kernel::ffi::c_void) {
345 if !device.is_null() {
346 // SAFETY: The caller ensures that the `device` pointer came from a previous call to
347 // `rust_binder_new_device`.
348 let ctx = unsafe { Arc::<Context>::from_foreign(device) };
349 ctx.deregister();
350 drop(ctx);
351 }
352}
353
354/// # Safety
355/// Only called by binderfs.
356unsafe extern "C" fn rust_binder_open(
357 inode: *mut bindings::inode,
358 file_ptr: *mut bindings::file,
359) -> kernel::ffi::c_int {
360 // SAFETY: The `rust_binderfs.c` file ensures that `i_private` is set to a
361 // `struct binder_device`.
362 let device = unsafe { (*inode).i_private } as *const binderfs::binder_device;
363
364 assert!(!device.is_null());
365
366 // SAFETY: The `rust_binderfs.c` file ensures that `device->ctx` holds a binder context when
367 // using the rust binder fops.
368 let ctx = unsafe { Arc::<Context>::borrow((*device).ctx) };
369
370 // SAFETY: The caller provides a valid file pointer to a new `struct file`.
371 let file = unsafe { File::from_raw_file(file_ptr) };
372 let process = match Process::open(ctx, file) {
373 Ok(process) => process,
374 Err(err) => return err.to_errno(),
375 };
376
377 // SAFETY: This is an `inode` for a newly created binder file.
378 match unsafe { BinderfsProcFile::new(inode, process.task.pid()) } {
379 Ok(Some(file)) => process.inner.lock().binderfs_file = Some(file),
380 Ok(None) => { /* pid already exists */ }
381 Err(err) => return err.to_errno(),
382 }
383
384 // SAFETY: This file is associated with Rust binder, so we own the `private_data` field.
385 unsafe { (*file_ptr).private_data = process.into_foreign() };
386 0
387}
388
389/// # Safety
390/// Only called by binderfs.
391unsafe extern "C" fn rust_binder_release(
392 _inode: *mut bindings::inode,
393 file: *mut bindings::file,
394) -> kernel::ffi::c_int {
395 // SAFETY: We previously set `private_data` in `rust_binder_open`.
396 let process = unsafe { Arc::<Process>::from_foreign((*file).private_data) };
397 // SAFETY: The caller ensures that the file is valid.
398 let file = unsafe { File::from_raw_file(file) };
399 Process::release(process, file);
400 0
401}
402
403/// # Safety
404/// Only called by binderfs.
405unsafe extern "C" fn rust_binder_ioctl(
406 file: *mut bindings::file,
407 cmd: kernel::ffi::c_uint,
408 arg: kernel::ffi::c_ulong,
409) -> kernel::ffi::c_long {
410 // SAFETY: We previously set `private_data` in `rust_binder_open`.
411 let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
412 // SAFETY: The caller ensures that the file is valid.
413 match Process::ioctl(f, unsafe { File::from_raw_file(file) }, cmd as _, arg as _) {
414 Ok(()) => 0,
415 Err(err) => err.to_errno() as isize,
416 }
417}
418
419/// # Safety
420/// Only called by binderfs.
421unsafe extern "C" fn rust_binder_mmap(
422 file: *mut bindings::file,
423 vma: *mut bindings::vm_area_struct,
424) -> kernel::ffi::c_int {
425 // SAFETY: We previously set `private_data` in `rust_binder_open`.
426 let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
427 // SAFETY: The caller ensures that the vma is valid.
428 let area = unsafe { kernel::mm::virt::VmaNew::from_raw(vma) };
429 // SAFETY: The caller ensures that the file is valid.
430 match Process::mmap(f, unsafe { File::from_raw_file(file) }, area) {
431 Ok(()) => 0,
432 Err(err) => err.to_errno(),
433 }
434}
435
436/// # Safety
437/// Only called by binderfs.
438unsafe extern "C" fn rust_binder_poll(
439 file: *mut bindings::file,
440 wait: *mut bindings::poll_table_struct,
441) -> bindings::__poll_t {
442 // SAFETY: We previously set `private_data` in `rust_binder_open`.
443 let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
444 // SAFETY: The caller ensures that the file is valid.
445 let fileref = unsafe { File::from_raw_file(file) };
446 // SAFETY: The caller ensures that the `PollTable` is valid.
447 match Process::poll(f, fileref, unsafe { PollTable::from_raw(wait) }) {
448 Ok(v) => v,
449 Err(_) => bindings::POLLERR,
450 }
451}
452
453/// # Safety
454/// Only called by binderfs.
455unsafe extern "C" fn rust_binder_flush(
456 file: *mut bindings::file,
457 _id: bindings::fl_owner_t,
458) -> kernel::ffi::c_int {
459 // SAFETY: We previously set `private_data` in `rust_binder_open`.
460 let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
461 match Process::flush(f) {
462 Ok(()) => 0,
463 Err(err) => err.to_errno(),
464 }
465}
466
467/// # Safety
468/// Only called by binderfs.
469#[no_mangle]
470unsafe extern "C" fn rust_binder_stats_show(
471 ptr: *mut seq_file,
472 _: *mut kernel::ffi::c_void,
473) -> kernel::ffi::c_int {
474 // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which
475 // this method is called.
476 let m = unsafe { SeqFile::from_raw(ptr) };
477 if let Err(err) = rust_binder_stats_show_impl(m) {
478 seq_print!(m, "failed to generate state: {:?}\n", err);
479 }
480 0
481}
482
483/// # Safety
484/// Only called by binderfs.
485#[no_mangle]
486unsafe extern "C" fn rust_binder_state_show(
487 ptr: *mut seq_file,
488 _: *mut kernel::ffi::c_void,
489) -> kernel::ffi::c_int {
490 // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which
491 // this method is called.
492 let m = unsafe { SeqFile::from_raw(ptr) };
493 if let Err(err) = rust_binder_state_show_impl(m) {
494 seq_print!(m, "failed to generate state: {:?}\n", err);
495 }
496 0
497}
498
499/// # Safety
500/// Only called by binderfs.
501#[no_mangle]
502unsafe extern "C" fn rust_binder_proc_show(
503 ptr: *mut seq_file,
504 _: *mut kernel::ffi::c_void,
505) -> kernel::ffi::c_int {
506 // SAFETY: Accessing the private field of `seq_file` is okay.
507 let pid = (unsafe { (*ptr).private }) as usize as Pid;
508 // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which
509 // this method is called.
510 let m = unsafe { SeqFile::from_raw(ptr) };
511 if let Err(err) = rust_binder_proc_show_impl(m, pid) {
512 seq_print!(m, "failed to generate state: {:?}\n", err);
513 }
514 0
515}
516
517/// # Safety
518/// Only called by binderfs.
519#[no_mangle]
520unsafe extern "C" fn rust_binder_transactions_show(
521 ptr: *mut seq_file,
522 _: *mut kernel::ffi::c_void,
523) -> kernel::ffi::c_int {
524 // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which
525 // this method is called.
526 let m = unsafe { SeqFile::from_raw(ptr) };
527 if let Err(err) = rust_binder_transactions_show_impl(m) {
528 seq_print!(m, "failed to generate state: {:?}\n", err);
529 }
530 0
531}
532
533fn rust_binder_transactions_show_impl(m: &SeqFile) -> Result<()> {
534 seq_print!(m, "binder transactions:\n");
535 let contexts = context::get_all_contexts()?;
536 for ctx in contexts {
537 let procs = ctx.get_all_procs()?;
538 for proc in procs {
539 proc.debug_print(m, &ctx, false)?;
540 seq_print!(m, "\n");
541 }
542 }
543 Ok(())
544}
545
546fn rust_binder_stats_show_impl(m: &SeqFile) -> Result<()> {
547 seq_print!(m, "binder stats:\n");
548 stats::GLOBAL_STATS.debug_print("", m);
549 let contexts = context::get_all_contexts()?;
550 for ctx in contexts {
551 let procs = ctx.get_all_procs()?;
552 for proc in procs {
553 proc.debug_print_stats(m, &ctx)?;
554 seq_print!(m, "\n");
555 }
556 }
557 Ok(())
558}
559
560fn rust_binder_state_show_impl(m: &SeqFile) -> Result<()> {
561 seq_print!(m, "binder state:\n");
562 let contexts = context::get_all_contexts()?;
563 for ctx in contexts {
564 let procs = ctx.get_all_procs()?;
565 for proc in procs {
566 proc.debug_print(m, &ctx, true)?;
567 seq_print!(m, "\n");
568 }
569 }
570 Ok(())
571}
572
573fn rust_binder_proc_show_impl(m: &SeqFile, pid: Pid) -> Result<()> {
574 seq_print!(m, "binder proc state:\n");
575 let contexts = context::get_all_contexts()?;
576 for ctx in contexts {
577 let procs = ctx.get_procs_with_pid(pid)?;
578 for proc in procs {
579 proc.debug_print(m, &ctx, true)?;
580 seq_print!(m, "\n");
581 }
582 }
583 Ok(())
584}
585
586struct BinderfsProcFile(NonNull<bindings::dentry>);
587
588// SAFETY: Safe to drop any thread.
589unsafe impl Send for BinderfsProcFile {}
590
591impl BinderfsProcFile {
592 /// # Safety
593 ///
594 /// Takes an inode from a newly created binder file.
595 unsafe fn new(nodp: *mut bindings::inode, pid: i32) -> Result<Option<Self>> {
596 // SAFETY: The caller passes an `inode` for a newly created binder file.
597 let dentry = unsafe { binderfs::rust_binderfs_create_proc_file(nodp, pid) };
598 match kernel::error::from_err_ptr(dentry) {
599 Ok(dentry) => Ok(NonNull::new(dentry).map(Self)),
600 Err(err) if err == EEXIST => Ok(None),
601 Err(err) => Err(err),
602 }
603 }
604}
605
606impl Drop for BinderfsProcFile {
607 fn drop(&mut self) {
608 // SAFETY: This is a dentry from `rust_binderfs_remove_file` that has not been deleted yet.
609 unsafe { binderfs::rust_binderfs_remove_file(self.0.as_ptr()) };
610 }
611}