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