xref: /linux/drivers/android/binder/rust_binder_main.rs (revision 6093a688a07da07808f0122f9aa2a3eed250d853)
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 
14 use 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 
29 use crate::{context::Context, page_range::Shrinker, process::Process, thread::Thread};
30 
31 use core::{
32     ptr::NonNull,
33     sync::atomic::{AtomicBool, AtomicUsize, Ordering},
34 };
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 fn 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`.
100 pub(crate) struct BinderReturnWriter<'a> {
101     writer: UserSliceWriter,
102     thread: &'a Thread,
103 }
104 
105 impl<'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.
134 trait 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]
159 struct DTRWrap<T: ?Sized> {
160     #[pin]
161     links: ListLinksSelfPtr<DTRWrap<dyn DeliverToRead>>,
162     #[pin]
163     wrapped: T,
164 }
165 kernel::list::impl_list_arc_safe! {
166     impl{T: ListArcSafe + ?Sized} ListArcSafe<0> for DTRWrap<T> {
167         tracked_by wrapped: T;
168     }
169 }
170 kernel::list::impl_list_item! {
171     impl ListItem<0> for DTRWrap<dyn DeliverToRead> {
172         using ListLinksSelfPtr { self.links };
173     }
174 }
175 
176 impl<T: ?Sized> core::ops::Deref for DTRWrap<T> {
177     type Target = T;
178     fn deref(&self) -> &T {
179         &self.wrapped
180     }
181 }
182 
183 type DArc<T> = kernel::sync::Arc<DTRWrap<T>>;
184 type DLArc<T> = kernel::list::ListArc<DTRWrap<T>>;
185 
186 impl<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 
216 struct DeliverCode {
217     code: u32,
218     skip: AtomicBool,
219 }
220 
221 kernel::list::impl_list_arc_safe! {
222     impl ListArcSafe<0> for DeliverCode { untracked; }
223 }
224 
225 impl 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 
242 impl 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 
274 fn 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`.
280 static BINDER_SHRINKER: Shrinker = unsafe { Shrinker::new() };
281 
282 struct BinderModule {}
283 
284 impl 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)]
302 pub struct AssertSync<T>(T);
303 // SAFETY: Used only to insert `file_operations` into a global, which is safe.
304 unsafe impl<T> Sync for AssertSync<T> {}
305 
306 /// File operations that rust_binderfs.c can use.
307 #[no_mangle]
308 #[used]
309 pub 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_unlocked_ioctl),
317         compat_ioctl: Some(rust_binder_compat_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]
330 unsafe 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]
344 unsafe 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.
356 unsafe 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.
391 unsafe 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.
405 unsafe extern "C" fn rust_binder_compat_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::compat_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.
421 unsafe extern "C" fn rust_binder_unlocked_ioctl(
422     file: *mut bindings::file,
423     cmd: kernel::ffi::c_uint,
424     arg: kernel::ffi::c_ulong,
425 ) -> kernel::ffi::c_long {
426     // SAFETY: We previously set `private_data` in `rust_binder_open`.
427     let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
428     // SAFETY: The caller ensures that the file is valid.
429     match Process::ioctl(f, unsafe { File::from_raw_file(file) }, cmd as _, arg as _) {
430         Ok(()) => 0,
431         Err(err) => err.to_errno() as isize,
432     }
433 }
434 
435 /// # Safety
436 /// Only called by binderfs.
437 unsafe extern "C" fn rust_binder_mmap(
438     file: *mut bindings::file,
439     vma: *mut bindings::vm_area_struct,
440 ) -> kernel::ffi::c_int {
441     // SAFETY: We previously set `private_data` in `rust_binder_open`.
442     let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
443     // SAFETY: The caller ensures that the vma is valid.
444     let area = unsafe { kernel::mm::virt::VmaNew::from_raw(vma) };
445     // SAFETY: The caller ensures that the file is valid.
446     match Process::mmap(f, unsafe { File::from_raw_file(file) }, area) {
447         Ok(()) => 0,
448         Err(err) => err.to_errno(),
449     }
450 }
451 
452 /// # Safety
453 /// Only called by binderfs.
454 unsafe extern "C" fn rust_binder_poll(
455     file: *mut bindings::file,
456     wait: *mut bindings::poll_table_struct,
457 ) -> bindings::__poll_t {
458     // SAFETY: We previously set `private_data` in `rust_binder_open`.
459     let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
460     // SAFETY: The caller ensures that the file is valid.
461     let fileref = unsafe { File::from_raw_file(file) };
462     // SAFETY: The caller ensures that the `PollTable` is valid.
463     match Process::poll(f, fileref, unsafe { PollTable::from_raw(wait) }) {
464         Ok(v) => v,
465         Err(_) => bindings::POLLERR,
466     }
467 }
468 
469 /// # Safety
470 /// Only called by binderfs.
471 unsafe extern "C" fn rust_binder_flush(
472     file: *mut bindings::file,
473     _id: bindings::fl_owner_t,
474 ) -> kernel::ffi::c_int {
475     // SAFETY: We previously set `private_data` in `rust_binder_open`.
476     let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
477     match Process::flush(f) {
478         Ok(()) => 0,
479         Err(err) => err.to_errno(),
480     }
481 }
482 
483 /// # Safety
484 /// Only called by binderfs.
485 #[no_mangle]
486 unsafe extern "C" fn rust_binder_stats_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_stats_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]
502 unsafe extern "C" fn rust_binder_state_show(
503     ptr: *mut seq_file,
504     _: *mut kernel::ffi::c_void,
505 ) -> kernel::ffi::c_int {
506     // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which
507     // this method is called.
508     let m = unsafe { SeqFile::from_raw(ptr) };
509     if let Err(err) = rust_binder_state_show_impl(m) {
510         seq_print!(m, "failed to generate state: {:?}\n", err);
511     }
512     0
513 }
514 
515 /// # Safety
516 /// Only called by binderfs.
517 #[no_mangle]
518 unsafe extern "C" fn rust_binder_proc_show(
519     ptr: *mut seq_file,
520     _: *mut kernel::ffi::c_void,
521 ) -> kernel::ffi::c_int {
522     // SAFETY: Accessing the private field of `seq_file` is okay.
523     let pid = (unsafe { (*ptr).private }) as usize as Pid;
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_proc_show_impl(m, pid) {
528         seq_print!(m, "failed to generate state: {:?}\n", err);
529     }
530     0
531 }
532 
533 /// # Safety
534 /// Only called by binderfs.
535 #[no_mangle]
536 unsafe extern "C" fn rust_binder_transactions_show(
537     ptr: *mut seq_file,
538     _: *mut kernel::ffi::c_void,
539 ) -> kernel::ffi::c_int {
540     // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which
541     // this method is called.
542     let m = unsafe { SeqFile::from_raw(ptr) };
543     if let Err(err) = rust_binder_transactions_show_impl(m) {
544         seq_print!(m, "failed to generate state: {:?}\n", err);
545     }
546     0
547 }
548 
549 fn rust_binder_transactions_show_impl(m: &SeqFile) -> Result<()> {
550     seq_print!(m, "binder transactions:\n");
551     let contexts = context::get_all_contexts()?;
552     for ctx in contexts {
553         let procs = ctx.get_all_procs()?;
554         for proc in procs {
555             proc.debug_print(m, &ctx, false)?;
556             seq_print!(m, "\n");
557         }
558     }
559     Ok(())
560 }
561 
562 fn rust_binder_stats_show_impl(m: &SeqFile) -> Result<()> {
563     seq_print!(m, "binder stats:\n");
564     stats::GLOBAL_STATS.debug_print("", m);
565     let contexts = context::get_all_contexts()?;
566     for ctx in contexts {
567         let procs = ctx.get_all_procs()?;
568         for proc in procs {
569             proc.debug_print_stats(m, &ctx)?;
570             seq_print!(m, "\n");
571         }
572     }
573     Ok(())
574 }
575 
576 fn rust_binder_state_show_impl(m: &SeqFile) -> Result<()> {
577     seq_print!(m, "binder state:\n");
578     let contexts = context::get_all_contexts()?;
579     for ctx in contexts {
580         let procs = ctx.get_all_procs()?;
581         for proc in procs {
582             proc.debug_print(m, &ctx, true)?;
583             seq_print!(m, "\n");
584         }
585     }
586     Ok(())
587 }
588 
589 fn rust_binder_proc_show_impl(m: &SeqFile, pid: Pid) -> Result<()> {
590     seq_print!(m, "binder proc state:\n");
591     let contexts = context::get_all_contexts()?;
592     for ctx in contexts {
593         let procs = ctx.get_procs_with_pid(pid)?;
594         for proc in procs {
595             proc.debug_print(m, &ctx, true)?;
596             seq_print!(m, "\n");
597         }
598     }
599     Ok(())
600 }
601 
602 struct BinderfsProcFile(NonNull<bindings::dentry>);
603 
604 // SAFETY: Safe to drop any thread.
605 unsafe impl Send for BinderfsProcFile {}
606 
607 impl BinderfsProcFile {
608     /// # Safety
609     ///
610     /// Takes an inode from a newly created binder file.
611     unsafe fn new(nodp: *mut bindings::inode, pid: i32) -> Result<Option<Self>> {
612         // SAFETY: The caller passes an `inode` for a newly created binder file.
613         let dentry = unsafe { binderfs::rust_binderfs_create_proc_file(nodp, pid) };
614         match kernel::error::from_err_ptr(dentry) {
615             Ok(dentry) => Ok(NonNull::new(dentry).map(Self)),
616             Err(err) if err == EEXIST => Ok(None),
617             Err(err) => Err(err),
618         }
619     }
620 }
621 
622 impl Drop for BinderfsProcFile {
623     fn drop(&mut self) {
624         // SAFETY: This is a dentry from `rust_binderfs_remove_file` that has not been deleted yet.
625         unsafe { binderfs::rust_binderfs_remove_file(self.0.as_ptr()) };
626     }
627 }
628