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