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