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