xref: /linux/drivers/android/binder/rust_binder_main.rs (revision 4dc0c899b14c3ea2c9b5f42b523301040d1c8100)
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         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 }
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) -> Self {
234         Self {
235             code,
236             skip: Atomic::new(false),
237         }
238     }
239 
240     /// Disable this DeliverCode and make it do nothing.
241     ///
242     /// This is used instead of removing it from the work list, since `LinkedList::remove` is
243     /// unsafe, whereas this method is not.
244     fn skip(&self) {
245         self.skip.store(true, Relaxed);
246     }
247 }
248 
249 impl DeliverToRead for DeliverCode {
250     fn do_work(
251         self: DArc<Self>,
252         _thread: &Thread,
253         writer: &mut BinderReturnWriter<'_>,
254     ) -> Result<bool> {
255         if !self.skip.load(Relaxed) {
256             writer.write_code(self.code)?;
257         }
258         Ok(true)
259     }
260 
261     fn cancel(self: DArc<Self>) {}
262 
263     fn should_sync_wakeup(&self) -> bool {
264         false
265     }
266 
267     fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> {
268         seq_print!(m, "{}", prefix);
269         if self.skip.load(Relaxed) {
270             seq_print!(m, "(skipped) ");
271         }
272         if self.code == defs::BR_TRANSACTION_COMPLETE {
273             seq_print!(m, "transaction complete\n");
274         } else {
275             seq_print!(m, "transaction error: {}\n", self.code);
276         }
277         Ok(())
278     }
279 }
280 
281 fn ptr_align(value: usize) -> Option<usize> {
282     let size = core::mem::size_of::<usize>() - 1;
283     Some(value.checked_add(size)? & !size)
284 }
285 
286 // SAFETY: We call register in `init`.
287 static BINDER_SHRINKER: Shrinker = unsafe { Shrinker::new() };
288 
289 struct BinderModule {}
290 
291 impl kernel::Module for BinderModule {
292     fn init(_module: &'static kernel::ThisModule) -> Result<Self> {
293         // SAFETY: The module initializer never runs twice, so we only call this once.
294         unsafe { crate::context::CONTEXTS.init() };
295 
296         BINDER_SHRINKER.register(c"android-binder")?;
297 
298         // SAFETY: The module is being loaded, so we can initialize binderfs.
299         unsafe { kernel::error::to_result(binderfs::init_rust_binderfs())? };
300 
301         Ok(Self {})
302     }
303 }
304 
305 /// Makes the inner type Sync.
306 #[repr(transparent)]
307 pub struct AssertSync<T>(T);
308 // SAFETY: Used only to insert `file_operations` into a global, which is safe.
309 unsafe impl<T> Sync for AssertSync<T> {}
310 
311 /// File operations that rust_binderfs.c can use.
312 #[no_mangle]
313 #[used]
314 pub static rust_binder_fops: AssertSync<kernel::bindings::file_operations> = {
315     // SAFETY: All zeroes is safe for the `file_operations` type.
316     let zeroed_ops = unsafe { core::mem::MaybeUninit::zeroed().assume_init() };
317 
318     let ops = kernel::bindings::file_operations {
319         owner: THIS_MODULE.as_ptr(),
320         poll: Some(rust_binder_poll),
321         unlocked_ioctl: Some(rust_binder_ioctl),
322         compat_ioctl: bindings::compat_ptr_ioctl,
323         mmap: Some(rust_binder_mmap),
324         open: Some(rust_binder_open),
325         release: Some(rust_binder_release),
326         flush: Some(rust_binder_flush),
327         ..zeroed_ops
328     };
329     AssertSync(ops)
330 };
331 
332 /// # Safety
333 /// Only called by binderfs.
334 #[no_mangle]
335 unsafe extern "C" fn rust_binder_new_context(
336     name: *const kernel::ffi::c_char,
337 ) -> *mut kernel::ffi::c_void {
338     // SAFETY: The caller will always provide a valid c string here.
339     let name = unsafe { kernel::str::CStr::from_char_ptr(name) };
340     match Context::new(name) {
341         Ok(ctx) => Arc::into_foreign(ctx),
342         Err(_err) => core::ptr::null_mut(),
343     }
344 }
345 
346 /// # Safety
347 /// Only called by binderfs.
348 #[no_mangle]
349 unsafe extern "C" fn rust_binder_remove_context(device: *mut kernel::ffi::c_void) {
350     if !device.is_null() {
351         // SAFETY: The caller ensures that the `device` pointer came from a previous call to
352         // `rust_binder_new_device`.
353         let ctx = unsafe { Arc::<Context>::from_foreign(device) };
354         ctx.deregister();
355         drop(ctx);
356     }
357 }
358 
359 /// # Safety
360 /// Only called by binderfs.
361 unsafe extern "C" fn rust_binder_open(
362     inode: *mut bindings::inode,
363     file_ptr: *mut bindings::file,
364 ) -> kernel::ffi::c_int {
365     // SAFETY: The `rust_binderfs.c` file ensures that `i_private` is set to a
366     // `struct binder_device`.
367     let device = unsafe { (*inode).i_private } as *const binderfs::binder_device;
368 
369     assert!(!device.is_null());
370 
371     // SAFETY: The `rust_binderfs.c` file ensures that `device->ctx` holds a binder context when
372     // using the rust binder fops.
373     let ctx = unsafe { Arc::<Context>::borrow((*device).ctx) };
374 
375     // SAFETY: The caller provides a valid file pointer to a new `struct file`.
376     let file = unsafe { File::from_raw_file(file_ptr) };
377     let process = match Process::open(ctx, file) {
378         Ok(process) => process,
379         Err(err) => return err.to_errno(),
380     };
381 
382     // SAFETY: This is an `inode` for a newly created binder file.
383     match unsafe { BinderfsProcFile::new(inode, process.task.pid()) } {
384         Ok(Some(file)) => process.inner.lock().binderfs_file = Some(file),
385         Ok(None) => { /* pid already exists */ }
386         Err(err) => return err.to_errno(),
387     }
388 
389     // SAFETY: This file is associated with Rust binder, so we own the `private_data` field.
390     unsafe { (*file_ptr).private_data = process.into_foreign() };
391     0
392 }
393 
394 /// # Safety
395 /// Only called by binderfs.
396 unsafe extern "C" fn rust_binder_release(
397     _inode: *mut bindings::inode,
398     file: *mut bindings::file,
399 ) -> kernel::ffi::c_int {
400     // SAFETY: We previously set `private_data` in `rust_binder_open`.
401     let process = unsafe { Arc::<Process>::from_foreign((*file).private_data) };
402     // SAFETY: The caller ensures that the file is valid.
403     let file = unsafe { File::from_raw_file(file) };
404     Process::release(process, file);
405     0
406 }
407 
408 /// # Safety
409 /// Only called by binderfs.
410 unsafe extern "C" fn rust_binder_ioctl(
411     file: *mut bindings::file,
412     cmd: kernel::ffi::c_uint,
413     arg: kernel::ffi::c_ulong,
414 ) -> kernel::ffi::c_long {
415     // SAFETY: We previously set `private_data` in `rust_binder_open`.
416     let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
417     // SAFETY: The caller ensures that the file is valid.
418     match Process::ioctl(f, unsafe { File::from_raw_file(file) }, cmd as _, arg as _) {
419         Ok(()) => 0,
420         Err(err) => err.to_errno() as isize,
421     }
422 }
423 
424 /// # Safety
425 /// Only called by binderfs.
426 unsafe extern "C" fn rust_binder_mmap(
427     file: *mut bindings::file,
428     vma: *mut bindings::vm_area_struct,
429 ) -> kernel::ffi::c_int {
430     // SAFETY: We previously set `private_data` in `rust_binder_open`.
431     let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
432     // SAFETY: The caller ensures that the vma is valid.
433     let area = unsafe { kernel::mm::virt::VmaNew::from_raw(vma) };
434     // SAFETY: The caller ensures that the file is valid.
435     match Process::mmap(f, unsafe { File::from_raw_file(file) }, area) {
436         Ok(()) => 0,
437         Err(err) => err.to_errno(),
438     }
439 }
440 
441 /// # Safety
442 /// Only called by binderfs.
443 unsafe extern "C" fn rust_binder_poll(
444     file: *mut bindings::file,
445     wait: *mut bindings::poll_table_struct,
446 ) -> bindings::__poll_t {
447     // SAFETY: We previously set `private_data` in `rust_binder_open`.
448     let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
449     // SAFETY: The caller ensures that the file is valid.
450     let fileref = unsafe { File::from_raw_file(file) };
451     // SAFETY: The caller ensures that the `PollTable` is valid.
452     match Process::poll(f, fileref, unsafe { PollTable::from_raw(wait) }) {
453         Ok(v) => v,
454         Err(_) => bindings::POLLERR,
455     }
456 }
457 
458 /// # Safety
459 /// Only called by binderfs.
460 unsafe extern "C" fn rust_binder_flush(
461     file: *mut bindings::file,
462     _id: bindings::fl_owner_t,
463 ) -> kernel::ffi::c_int {
464     // SAFETY: We previously set `private_data` in `rust_binder_open`.
465     let f = unsafe { Arc::<Process>::borrow((*file).private_data) };
466     match Process::flush(f) {
467         Ok(()) => 0,
468         Err(err) => err.to_errno(),
469     }
470 }
471 
472 /// # Safety
473 /// Only called by binderfs.
474 #[no_mangle]
475 unsafe extern "C" fn rust_binder_stats_show(
476     ptr: *mut seq_file,
477     _: *mut kernel::ffi::c_void,
478 ) -> kernel::ffi::c_int {
479     // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which
480     // this method is called.
481     let m = unsafe { SeqFile::from_raw(ptr) };
482     if let Err(err) = rust_binder_stats_show_impl(m) {
483         seq_print!(m, "failed to generate state: {:?}\n", err);
484     }
485     0
486 }
487 
488 /// # Safety
489 /// Only called by binderfs.
490 #[no_mangle]
491 unsafe extern "C" fn rust_binder_state_show(
492     ptr: *mut seq_file,
493     _: *mut kernel::ffi::c_void,
494 ) -> kernel::ffi::c_int {
495     // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which
496     // this method is called.
497     let m = unsafe { SeqFile::from_raw(ptr) };
498     if let Err(err) = rust_binder_state_show_impl(m) {
499         seq_print!(m, "failed to generate state: {:?}\n", err);
500     }
501     0
502 }
503 
504 /// # Safety
505 /// Only called by binderfs.
506 #[no_mangle]
507 unsafe extern "C" fn rust_binder_proc_show(
508     ptr: *mut seq_file,
509     _: *mut kernel::ffi::c_void,
510 ) -> kernel::ffi::c_int {
511     // SAFETY: Accessing the private field of `seq_file` is okay.
512     let pid = (unsafe { (*ptr).private }) as usize as Pid;
513     // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which
514     // this method is called.
515     let m = unsafe { SeqFile::from_raw(ptr) };
516     if let Err(err) = rust_binder_proc_show_impl(m, pid) {
517         seq_print!(m, "failed to generate state: {:?}\n", err);
518     }
519     0
520 }
521 
522 /// # Safety
523 /// Only called by binderfs.
524 #[no_mangle]
525 unsafe extern "C" fn rust_binder_transactions_show(
526     ptr: *mut seq_file,
527     _: *mut kernel::ffi::c_void,
528 ) -> kernel::ffi::c_int {
529     // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which
530     // this method is called.
531     let m = unsafe { SeqFile::from_raw(ptr) };
532     if let Err(err) = rust_binder_transactions_show_impl(m) {
533         seq_print!(m, "failed to generate state: {:?}\n", err);
534     }
535     0
536 }
537 
538 fn rust_binder_transactions_show_impl(m: &SeqFile) -> Result<()> {
539     seq_print!(m, "binder transactions:\n");
540     let contexts = context::get_all_contexts()?;
541     for ctx in contexts {
542         let procs = ctx.get_all_procs()?;
543         for proc in procs {
544             proc.debug_print(m, &ctx, false)?;
545             seq_print!(m, "\n");
546         }
547     }
548     Ok(())
549 }
550 
551 fn rust_binder_stats_show_impl(m: &SeqFile) -> Result<()> {
552     seq_print!(m, "binder stats:\n");
553     stats::GLOBAL_STATS.debug_print("", m);
554     let contexts = context::get_all_contexts()?;
555     for ctx in contexts {
556         let procs = ctx.get_all_procs()?;
557         for proc in procs {
558             proc.debug_print_stats(m, &ctx)?;
559             seq_print!(m, "\n");
560         }
561     }
562     Ok(())
563 }
564 
565 fn rust_binder_state_show_impl(m: &SeqFile) -> Result<()> {
566     seq_print!(m, "binder state:\n");
567     let contexts = context::get_all_contexts()?;
568     for ctx in contexts {
569         let procs = ctx.get_all_procs()?;
570         for proc in procs {
571             proc.debug_print(m, &ctx, true)?;
572             seq_print!(m, "\n");
573         }
574     }
575     Ok(())
576 }
577 
578 fn rust_binder_proc_show_impl(m: &SeqFile, pid: Pid) -> Result<()> {
579     seq_print!(m, "binder proc state:\n");
580     let contexts = context::get_all_contexts()?;
581     for ctx in contexts {
582         let procs = ctx.get_procs_with_pid(pid)?;
583         for proc in procs {
584             proc.debug_print(m, &ctx, true)?;
585             seq_print!(m, "\n");
586         }
587     }
588     Ok(())
589 }
590 
591 struct BinderfsProcFile(NonNull<bindings::dentry>);
592 
593 // SAFETY: Safe to drop any thread.
594 unsafe impl Send for BinderfsProcFile {}
595 
596 impl BinderfsProcFile {
597     /// # Safety
598     ///
599     /// Takes an inode from a newly created binder file.
600     unsafe fn new(nodp: *mut bindings::inode, pid: i32) -> Result<Option<Self>> {
601         // SAFETY: The caller passes an `inode` for a newly created binder file.
602         let dentry = unsafe { binderfs::rust_binderfs_create_proc_file(nodp, pid) };
603         match kernel::error::from_err_ptr(dentry) {
604             Ok(dentry) => Ok(NonNull::new(dentry).map(Self)),
605             Err(err) if err == EEXIST => Ok(None),
606             Err(err) => Err(err),
607         }
608     }
609 }
610 
611 impl Drop for BinderfsProcFile {
612     fn drop(&mut self) {
613         // SAFETY: This is a dentry from `rust_binderfs_remove_file` that has not been deleted yet.
614         unsafe { binderfs::rust_binderfs_remove_file(self.0.as_ptr()) };
615     }
616 }
617