xref: /linux/drivers/android/binder/rust_binder_main.rs (revision c16ce856e422e73a54c41131e0332de1afe09b8b)
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 #[macro_use]
35 mod debug;
36 mod error;
37 mod netlink;
38 mod node;
39 mod page_range;
40 mod process;
41 mod range_alloc;
42 mod stats;
43 mod thread;
44 mod trace;
45 mod transaction;
46 
47 #[allow(warnings)] // generated bindgen code
48 mod binderfs {
49     use kernel::bindings::{dentry, inode};
50 
51     extern "C" {
52         pub fn init_rust_binderfs() -> kernel::ffi::c_int;
53     }
54     extern "C" {
55         pub fn rust_binderfs_create_proc_file(
56             nodp: *mut inode,
57             pid: kernel::ffi::c_int,
58         ) -> *mut dentry;
59     }
60     extern "C" {
61         pub fn rust_binderfs_remove_file(dentry: *mut dentry);
62     }
63     pub type rust_binder_context = *mut kernel::ffi::c_void;
64     #[repr(C)]
65     #[derive(Copy, Clone)]
66     pub struct binder_device {
67         pub minor: kernel::ffi::c_int,
68         pub ctx: rust_binder_context,
69     }
70     impl Default for binder_device {
71         fn default() -> Self {
72             let mut s = ::core::mem::MaybeUninit::<Self>::uninit();
73             unsafe {
74                 ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1);
75                 s.assume_init()
76             }
77         }
78     }
79 }
80 
81 module! {
82     type: BinderModule,
83     name: "rust_binder",
84     authors: ["Wedson Almeida Filho", "Alice Ryhl"],
85     description: "Android Binder",
86     license: "GPL",
87 }
88 
89 use kernel::bindings::rust_binder_layout;
90 #[no_mangle]
91 static RUST_BINDER_LAYOUT: rust_binder_layout = rust_binder_layout {
92     t: transaction::TRANSACTION_LAYOUT,
93     p: process::PROCESS_LAYOUT,
94     n: node::NODE_LAYOUT,
95 };
96 
97 fn next_debug_id() -> usize {
98     static NEXT_DEBUG_ID: Atomic<usize> = Atomic::new(0);
99 
100     NEXT_DEBUG_ID.fetch_add(1, Relaxed)
101 }
102 
103 /// Provides a single place to write Binder return values via the
104 /// supplied `UserSliceWriter`.
105 pub(crate) struct BinderReturnWriter<'a> {
106     writer: UserSliceWriter,
107     thread: &'a Thread,
108 }
109 
110 impl<'a> BinderReturnWriter<'a> {
111     fn new(writer: UserSliceWriter, thread: &'a Thread) -> Self {
112         BinderReturnWriter { writer, thread }
113     }
114 
115     /// Write a return code back to user space.
116     /// Should be a `BR_` constant from [`defs`] e.g. [`defs::BR_TRANSACTION_COMPLETE`].
117     fn write_code(&mut self, code: u32) -> Result {
118         crate::trace::trace_return(code);
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     pid: i32,
226 }
227 
228 kernel::list::impl_list_arc_safe! {
229     impl ListArcSafe<0> for DeliverCode { untracked; }
230 }
231 
232 impl DeliverCode {
233     fn new(code: u32, pid: i32) -> Self {
234         Self {
235             code,
236             skip: Atomic::new(false),
237             pid,
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, 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(Relaxed) {
257             writer.write_code(self.code)?;
258         }
259         Ok(true)
260     }
261 
262     fn cancel(self: DArc<Self>) {
263         if !self.skip.load(Relaxed) {
264             binder_debug!(
265                 pid = self.pid,
266                 DeadTransaction,
267                 "undelivered TRANSACTION_COMPLETE"
268             );
269         }
270     }
271 
272     fn should_sync_wakeup(&self) -> bool {
273         false
274     }
275 
276     fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> {
277         seq_print!(m, "{}", prefix);
278         if self.skip.load(Relaxed) {
279             seq_print!(m, "(skipped) ");
280         }
281         if self.code == defs::BR_TRANSACTION_COMPLETE {
282             seq_print!(m, "transaction complete\n");
283         } else {
284             seq_print!(m, "transaction error: {}\n", self.code);
285         }
286         Ok(())
287     }
288 }
289 
290 fn ptr_align(value: usize) -> Option<usize> {
291     let size = core::mem::size_of::<usize>() - 1;
292     Some(value.checked_add(size)? & !size)
293 }
294 
295 // SAFETY: We call register in `init`.
296 static BINDER_SHRINKER: Shrinker = unsafe { Shrinker::new() };
297 
298 struct BinderModule {
299     _netlink: kernel::net::netlink::Registration,
300 }
301 
302 impl kernel::Module for BinderModule {
303     fn init(_module: &'static kernel::ThisModule) -> Result<Self> {
304         // SAFETY: The module initializer never runs twice, so we only call this once.
305         unsafe { crate::context::CONTEXTS.init() };
306 
307         let netlink = crate::netlink::BINDER_NL_FAMILY.register()?;
308         BINDER_SHRINKER.register(c"android-binder")?;
309 
310         // SAFETY: The module is being loaded, so we can initialize binderfs.
311         unsafe { kernel::error::to_result(binderfs::init_rust_binderfs())? };
312 
313         Ok(Self { _netlink: netlink })
314     }
315 }
316 
317 /// Makes the inner type Sync.
318 #[repr(transparent)]
319 pub struct AssertSync<T>(T);
320 // SAFETY: Used only to insert C bindings types into globals, which is safe.
321 unsafe impl<T> Sync for AssertSync<T> {}
322 
323 /// File operations that rust_binderfs.c can use.
324 #[no_mangle]
325 #[used]
326 pub static rust_binder_fops: AssertSync<kernel::bindings::file_operations> = {
327     let ops = kernel::bindings::file_operations {
328         owner: THIS_MODULE.as_ptr(),
329         poll: Some(rust_binder_poll),
330         unlocked_ioctl: Some(rust_binder_ioctl),
331         compat_ioctl: bindings::compat_ptr_ioctl,
332         mmap: Some(rust_binder_mmap),
333         open: Some(rust_binder_open),
334         release: Some(rust_binder_release),
335         flush: Some(rust_binder_flush),
336         ..pin_init::zeroed()
337     };
338     AssertSync(ops)
339 };
340 
341 /// # Safety
342 /// Only called by binderfs.
343 #[no_mangle]
344 unsafe extern "C" fn rust_binder_new_context(
345     name: *const kernel::ffi::c_char,
346 ) -> *mut kernel::ffi::c_void {
347     // SAFETY: The caller will always provide a valid c string here.
348     let name = unsafe { kernel::str::CStr::from_char_ptr(name) };
349     match Context::new(name) {
350         Ok(ctx) => Arc::into_foreign(ctx),
351         Err(_err) => core::ptr::null_mut(),
352     }
353 }
354 
355 /// # Safety
356 /// Only called by binderfs.
357 #[no_mangle]
358 unsafe extern "C" fn rust_binder_remove_context(device: *mut kernel::ffi::c_void) {
359     if !device.is_null() {
360         // SAFETY: The caller ensures that the `device` pointer came from a previous call to
361         // `rust_binder_new_device`.
362         let ctx = unsafe { Arc::<Context>::from_foreign(device) };
363         ctx.deregister();
364         drop(ctx);
365     }
366 }
367 
368 /// # Safety
369 /// Only called by binderfs.
370 unsafe extern "C" fn rust_binder_open(
371     inode: *mut bindings::inode,
372     file_ptr: *mut bindings::file,
373 ) -> kernel::ffi::c_int {
374     // SAFETY: The `rust_binderfs.c` file ensures that `i_private` is set to a
375     // `struct binder_device`.
376     let device = unsafe { (*inode).i_private } as *const binderfs::binder_device;
377 
378     assert!(!device.is_null());
379 
380     // SAFETY: The `rust_binderfs.c` file ensures that `device->ctx` holds a binder context when
381     // using the rust binder fops.
382     let ctx = unsafe { Arc::<Context>::borrow((*device).ctx) };
383 
384     // SAFETY: The caller provides a valid file pointer to a new `struct file`.
385     let file = unsafe { File::from_raw_file(file_ptr) };
386     let process = match Process::open(ctx, file) {
387         Ok(process) => process,
388         Err(err) => return err.to_errno(),
389     };
390 
391     // SAFETY: This is an `inode` for a newly created binder file.
392     match unsafe { BinderfsProcFile::new(inode, process.task.pid()) } {
393         Ok(Some(file)) => process.inner.lock().binderfs_file = Some(file),
394         Ok(None) => { /* pid already exists */ }
395         Err(err) => return err.to_errno(),
396     }
397 
398     // SAFETY: This file is associated with Rust binder, so we own the `private_data` field.
399     unsafe { (*file_ptr).private_data = process.into_foreign() };
400     0
401 }
402 
403 /// # Safety
404 /// Only called by binderfs.
405 unsafe extern "C" fn rust_binder_release(
406     _inode: *mut bindings::inode,
407     file: *mut bindings::file,
408 ) -> kernel::ffi::c_int {
409     // SAFETY: We previously set `private_data` in `rust_binder_open`.
410     let process = unsafe { Arc::<Process>::from_foreign((*file).private_data) };
411     // SAFETY: The caller ensures that the file is valid.
412     let file = unsafe { File::from_raw_file(file) };
413     Process::release(process, file);
414     0
415 }
416 
417 /// # Safety
418 /// Only called by binderfs.
419 unsafe extern "C" fn rust_binder_ioctl(
420     file: *mut bindings::file,
421     cmd: kernel::ffi::c_uint,
422     arg: kernel::ffi::c_ulong,
423 ) -> kernel::ffi::c_long {
424     // SAFETY: We previously set `private_data` in `rust_binder_open`.
425     let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
426     // SAFETY: The caller ensures that the file is valid.
427     match Process::ioctl(f, unsafe { File::from_raw_file(file) }, cmd, arg) {
428         Ok(()) => 0,
429         Err(err) => err.to_errno() as isize,
430     }
431 }
432 
433 /// # Safety
434 /// Only called by binderfs.
435 unsafe extern "C" fn rust_binder_mmap(
436     file: *mut bindings::file,
437     vma: *mut bindings::vm_area_struct,
438 ) -> kernel::ffi::c_int {
439     // SAFETY: We previously set `private_data` in `rust_binder_open`.
440     let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
441     // SAFETY: The caller ensures that the vma is valid.
442     let area = unsafe { kernel::mm::virt::VmaNew::from_raw(vma) };
443     // SAFETY: The caller ensures that the file is valid.
444     match Process::mmap(f, unsafe { File::from_raw_file(file) }, area) {
445         Ok(()) => 0,
446         Err(err) => err.to_errno(),
447     }
448 }
449 
450 /// # Safety
451 /// Only called by binderfs.
452 unsafe extern "C" fn rust_binder_poll(
453     file: *mut bindings::file,
454     wait: *mut bindings::poll_table_struct,
455 ) -> bindings::__poll_t {
456     // SAFETY: We previously set `private_data` in `rust_binder_open`.
457     let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
458     // SAFETY: The caller ensures that the file is valid.
459     let fileref = unsafe { File::from_raw_file(file) };
460     // SAFETY: The caller ensures that the `PollTable` is valid.
461     match Process::poll(f, fileref, unsafe { PollTable::from_raw(wait) }) {
462         Ok(v) => v,
463         Err(_) => bindings::POLLERR,
464     }
465 }
466 
467 /// # Safety
468 /// Only called by binderfs.
469 unsafe extern "C" fn rust_binder_flush(
470     file: *mut bindings::file,
471     _id: bindings::fl_owner_t,
472 ) -> kernel::ffi::c_int {
473     // SAFETY: We previously set `private_data` in `rust_binder_open`.
474     let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
475     match Process::flush(f) {
476         Ok(()) => 0,
477         Err(err) => err.to_errno(),
478     }
479 }
480 
481 /// # Safety
482 /// Only called by binderfs.
483 #[no_mangle]
484 unsafe extern "C" fn rust_binder_stats_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_stats_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_state_show(
501     ptr: *mut seq_file,
502     _: *mut kernel::ffi::c_void,
503 ) -> kernel::ffi::c_int {
504     // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which
505     // this method is called.
506     let m = unsafe { SeqFile::from_raw(ptr) };
507     if let Err(err) = rust_binder_state_show_impl(m) {
508         seq_print!(m, "failed to generate state: {:?}\n", err);
509     }
510     0
511 }
512 
513 /// # Safety
514 /// Only called by binderfs.
515 #[no_mangle]
516 unsafe extern "C" fn rust_binder_proc_show(
517     ptr: *mut seq_file,
518     _: *mut kernel::ffi::c_void,
519 ) -> kernel::ffi::c_int {
520     // SAFETY: Accessing the private field of `seq_file` is okay.
521     let pid = unsafe { (*ptr).private }.addr() as Pid;
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_proc_show_impl(m, pid) {
526         seq_print!(m, "failed to generate state: {:?}\n", err);
527     }
528     0
529 }
530 
531 /// # Safety
532 /// Only called by binderfs.
533 #[no_mangle]
534 unsafe extern "C" fn rust_binder_transactions_show(
535     ptr: *mut seq_file,
536     _: *mut kernel::ffi::c_void,
537 ) -> kernel::ffi::c_int {
538     // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which
539     // this method is called.
540     let m = unsafe { SeqFile::from_raw(ptr) };
541     if let Err(err) = rust_binder_transactions_show_impl(m) {
542         seq_print!(m, "failed to generate state: {:?}\n", err);
543     }
544     0
545 }
546 
547 fn rust_binder_transactions_show_impl(m: &SeqFile) -> Result<()> {
548     seq_print!(m, "binder transactions:\n");
549     let contexts = context::get_all_contexts()?;
550     for ctx in contexts {
551         let procs = ctx.get_all_procs()?;
552         for proc in procs {
553             proc.debug_print(m, &ctx, false)?;
554             seq_print!(m, "\n");
555         }
556     }
557     Ok(())
558 }
559 
560 fn rust_binder_stats_show_impl(m: &SeqFile) -> Result<()> {
561     seq_print!(m, "binder stats:\n");
562     stats::GLOBAL_STATS.debug_print("", m);
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_stats(m, &ctx)?;
568             seq_print!(m, "\n");
569         }
570     }
571     Ok(())
572 }
573 
574 fn rust_binder_state_show_impl(m: &SeqFile) -> Result<()> {
575     seq_print!(m, "binder state:\n");
576     let contexts = context::get_all_contexts()?;
577     for ctx in contexts {
578         let procs = ctx.get_all_procs()?;
579         for proc in procs {
580             proc.debug_print(m, &ctx, true)?;
581             seq_print!(m, "\n");
582         }
583     }
584     Ok(())
585 }
586 
587 fn rust_binder_proc_show_impl(m: &SeqFile, pid: Pid) -> Result<()> {
588     seq_print!(m, "binder proc state:\n");
589     let contexts = context::get_all_contexts()?;
590     for ctx in contexts {
591         let procs = ctx.get_procs_with_pid(pid)?;
592         for proc in procs {
593             proc.debug_print(m, &ctx, true)?;
594             seq_print!(m, "\n");
595         }
596     }
597     Ok(())
598 }
599 
600 struct BinderfsProcFile(NonNull<bindings::dentry>);
601 
602 // SAFETY: Safe to drop any thread.
603 unsafe impl Send for BinderfsProcFile {}
604 
605 impl BinderfsProcFile {
606     /// # Safety
607     ///
608     /// Takes an inode from a newly created binder file.
609     unsafe fn new(nodp: *mut bindings::inode, pid: i32) -> Result<Option<Self>> {
610         // SAFETY: The caller passes an `inode` for a newly created binder file.
611         let dentry = unsafe { binderfs::rust_binderfs_create_proc_file(nodp, pid) };
612         match kernel::error::from_err_ptr(dentry) {
613             Ok(dentry) => Ok(NonNull::new(dentry).map(Self)),
614             Err(err) if err == EEXIST => Ok(None),
615             Err(err) => Err(err),
616         }
617     }
618 }
619 
620 impl Drop for BinderfsProcFile {
621     fn drop(&mut self) {
622         // SAFETY: This is a dentry from `rust_binderfs_remove_file` that has not been deleted yet.
623         unsafe { binderfs::rust_binderfs_remove_file(self.0.as_ptr()) };
624     }
625 }
626