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