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