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