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