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