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