xref: /linux/drivers/android/binder/rust_binder_main.rs (revision 85cdaca6970028bf6f544c355c90035586836ddf)
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     module::this_module,
21     prelude::*,
22     seq_file::SeqFile,
23     seq_print,
24     sync::atomic::{ordering::Relaxed, Atomic},
25     sync::poll::PollTable,
26     sync::Arc,
27     task::Pid,
28     transmute::AsBytes,
29     types::ForeignOwnable,
30     uaccess::UserSliceWriter,
31 };
32 
33 use crate::{context::Context, page_range::Shrinker, process::Process, thread::Thread};
34 
35 use core::ptr::NonNull;
36 
37 mod allocation;
38 mod context;
39 mod deferred_close;
40 mod defs;
41 mod error;
42 mod node;
43 mod page_range;
44 mod process;
45 mod range_alloc;
46 mod stats;
47 mod thread;
48 mod trace;
49 mod transaction;
50 
51 #[allow(warnings)] // generated bindgen code
52 mod binderfs {
53     use kernel::bindings::{dentry, inode};
54 
55     extern "C" {
56         pub fn init_rust_binderfs() -> kernel::ffi::c_int;
57     }
58     extern "C" {
59         pub fn rust_binderfs_create_proc_file(
60             nodp: *mut inode,
61             pid: kernel::ffi::c_int,
62         ) -> *mut dentry;
63     }
64     extern "C" {
65         pub fn rust_binderfs_remove_file(dentry: *mut dentry);
66     }
67     pub type rust_binder_context = *mut kernel::ffi::c_void;
68     #[repr(C)]
69     #[derive(Copy, Clone)]
70     pub struct binder_device {
71         pub minor: kernel::ffi::c_int,
72         pub ctx: rust_binder_context,
73     }
74     impl Default for binder_device {
75         fn default() -> Self {
76             let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
77             unsafe {
78                 ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
79                 s.assume_init()
80             }
81         }
82     }
83 }
84 
85 module! {
86     type: BinderModule,
87     name: "rust_binder",
88     authors: ["Wedson Almeida Filho", "Alice Ryhl"],
89     description: "Android Binder",
90     license: "GPL",
91 }
92 
93 use kernel::bindings::rust_binder_layout;
94 #[no_mangle]
95 static RUST_BINDER_LAYOUT: rust_binder_layout = rust_binder_layout {
96     t: transaction::TRANSACTION_LAYOUT,
97     p: process::PROCESS_LAYOUT,
98     n: node::NODE_LAYOUT,
99 };
100 
101 fn next_debug_id() -> usize {
102     static NEXT_DEBUG_ID: Atomic<usize> = Atomic::new(0);
103 
104     NEXT_DEBUG_ID.fetch_add(1, Relaxed)
105 }
106 
107 /// Provides a single place to write Binder return values via the
108 /// supplied `UserSliceWriter`.
109 pub(crate) struct BinderReturnWriter<'a> {
110     writer: UserSliceWriter,
111     thread: &'a Thread,
112 }
113 
114 impl<'a> BinderReturnWriter<'a> {
115     fn new(writer: UserSliceWriter, thread: &'a Thread) -> Self {
116         BinderReturnWriter { writer, thread }
117     }
118 
119     /// Write a return code back to user space.
120     /// Should be a `BR_` constant from [`defs`] e.g. [`defs::BR_TRANSACTION_COMPLETE`].
121     fn write_code(&mut self, code: u32) -> Result {
122         crate::trace::trace_return(code);
123         stats::GLOBAL_STATS.inc_br(code);
124         self.thread.process.stats.inc_br(code);
125         self.writer.write(&code)
126     }
127 
128     /// Write something *other than* a return code to user space.
129     fn write_payload<T: AsBytes>(&mut self, payload: &T) -> Result {
130         self.writer.write(payload)
131     }
132 
133     fn len(&self) -> usize {
134         self.writer.len()
135     }
136 }
137 
138 /// Specifies how a type should be delivered to the read part of a BINDER_WRITE_READ ioctl.
139 ///
140 /// When a value is pushed to the todo list for a process or thread, it is stored as a trait object
141 /// with the type `Arc<dyn DeliverToRead>`. Trait objects are a Rust feature that lets you
142 /// implement dynamic dispatch over many different types. This lets us store many different types
143 /// in the todo list.
144 trait DeliverToRead: ListArcSafe + Send + Sync {
145     /// Performs work. Returns true if remaining work items in the queue should be processed
146     /// immediately, or false if it should return to caller before processing additional work
147     /// items.
148     fn do_work(
149         self: DArc<Self>,
150         thread: &Thread,
151         writer: &mut BinderReturnWriter<'_>,
152     ) -> Result<bool>;
153 
154     /// Cancels the given work item. This is called instead of [`DeliverToRead::do_work`] when work
155     /// won't be delivered.
156     fn cancel(self: DArc<Self>);
157 
158     /// Should we use `wake_up_interruptible_sync` or `wake_up_interruptible` when scheduling this
159     /// work item?
160     ///
161     /// Generally only set to true for non-oneway transactions.
162     fn should_sync_wakeup(&self) -> bool;
163 
164     fn debug_print(&self, m: &SeqFile, prefix: &str, transaction_prefix: &str) -> Result<()>;
165 }
166 
167 // Wrapper around a `DeliverToRead` with linked list links.
168 #[pin_data]
169 struct DTRWrap<T: ?Sized> {
170     #[pin]
171     links: ListLinksSelfPtr<DTRWrap<dyn DeliverToRead>>,
172     #[pin]
173     wrapped: T,
174 }
175 kernel::list::impl_list_arc_safe! {
176     impl{T: ListArcSafe + ?Sized} ListArcSafe<0> for DTRWrap<T> {
177         tracked_by wrapped: T;
178     }
179 }
180 kernel::list::impl_list_item! {
181     impl ListItem<0> for DTRWrap<dyn DeliverToRead> {
182         using ListLinksSelfPtr { self.links };
183     }
184 }
185 
186 impl<T: ?Sized> core::ops::Deref for DTRWrap<T> {
187     type Target = T;
188     fn deref(&self) -> &T {
189         &self.wrapped
190     }
191 }
192 
193 type DArc<T> = kernel::sync::Arc<DTRWrap<T>>;
194 type DLArc<T> = kernel::list::ListArc<DTRWrap<T>>;
195 
196 impl<T: ListArcSafe> DTRWrap<T> {
197     fn new(val: impl PinInit<T>) -> impl PinInit<Self> {
198         pin_init!(Self {
199             links <- ListLinksSelfPtr::new(),
200             wrapped <- val,
201         })
202     }
203 
204     fn arc_try_new(val: T) -> Result<DLArc<T>, kernel::alloc::AllocError> {
205         ListArc::pin_init(
206             try_pin_init!(Self {
207                 links <- ListLinksSelfPtr::new(),
208                 wrapped: val,
209             }),
210             GFP_KERNEL,
211         )
212         .map_err(|_| kernel::alloc::AllocError)
213     }
214 
215     fn arc_pin_init(init: impl PinInit<T>) -> Result<DLArc<T>, kernel::error::Error> {
216         ListArc::pin_init(
217             try_pin_init!(Self {
218                 links <- ListLinksSelfPtr::new(),
219                 wrapped <- init,
220             }),
221             GFP_KERNEL,
222         )
223     }
224 }
225 
226 struct DeliverCode {
227     code: u32,
228     skip: Atomic<bool>,
229 }
230 
231 kernel::list::impl_list_arc_safe! {
232     impl ListArcSafe<0> for DeliverCode { untracked; }
233 }
234 
235 impl DeliverCode {
236     fn new(code: u32) -> Self {
237         Self {
238             code,
239             skip: Atomic::new(false),
240         }
241     }
242 
243     /// Disable this DeliverCode and make it do nothing.
244     ///
245     /// This is used instead of removing it from the work list, since `LinkedList::remove` is
246     /// unsafe, whereas this method is not.
247     fn skip(&self) {
248         self.skip.store(true, Relaxed);
249     }
250 }
251 
252 impl DeliverToRead for DeliverCode {
253     fn do_work(
254         self: DArc<Self>,
255         _thread: &Thread,
256         writer: &mut BinderReturnWriter<'_>,
257     ) -> Result<bool> {
258         if !self.skip.load(Relaxed) {
259             writer.write_code(self.code)?;
260         }
261         Ok(true)
262     }
263 
264     fn cancel(self: DArc<Self>) {}
265 
266     fn should_sync_wakeup(&self) -> bool {
267         false
268     }
269 
270     fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> {
271         seq_print!(m, "{}", prefix);
272         if self.skip.load(Relaxed) {
273             seq_print!(m, "(skipped) ");
274         }
275         if self.code == defs::BR_TRANSACTION_COMPLETE {
276             seq_print!(m, "transaction complete\n");
277         } else {
278             seq_print!(m, "transaction error: {}\n", self.code);
279         }
280         Ok(())
281     }
282 }
283 
284 fn ptr_align(value: usize) -> Option<usize> {
285     let size = core::mem::size_of::<usize>() - 1;
286     Some(value.checked_add(size)? & !size)
287 }
288 
289 // SAFETY: We call register in `init`.
290 static BINDER_SHRINKER: Shrinker = unsafe { Shrinker::new() };
291 
292 struct BinderModule {}
293 
294 impl kernel::Module for BinderModule {
295     fn init(_module: &'static kernel::ThisModule) -> Result<Self> {
296         // SAFETY: The module initializer never runs twice, so we only call this once.
297         unsafe { crate::context::CONTEXTS.init() };
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 C bindings types into globals, 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::<LocalModule>().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