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