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