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