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