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