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 #[macro_use] 35 mod debug; 36 mod error; 37 mod netlink; 38 mod node; 39 mod page_range; 40 mod process; 41 mod range_alloc; 42 mod stats; 43 mod thread; 44 mod trace; 45 mod transaction; 46 47 #[allow(warnings)] // generated bindgen code 48 mod binderfs { 49 use kernel::bindings::{dentry, inode}; 50 51 extern "C" { 52 pub fn init_rust_binderfs() -> kernel::ffi::c_int; 53 } 54 extern "C" { 55 pub fn rust_binderfs_create_proc_file( 56 nodp: *mut inode, 57 pid: kernel::ffi::c_int, 58 ) -> *mut dentry; 59 } 60 extern "C" { 61 pub fn rust_binderfs_remove_file(dentry: *mut dentry); 62 } 63 pub type rust_binder_context = *mut kernel::ffi::c_void; 64 #[repr(C)] 65 #[derive(Copy, Clone)] 66 pub struct binder_device { 67 pub minor: kernel::ffi::c_int, 68 pub ctx: rust_binder_context, 69 } 70 impl Default for binder_device { 71 fn default() -> Self { 72 let mut s = ::core::mem::MaybeUninit::<Self>::uninit(); 73 unsafe { 74 ::core::ptr::write_bytes(s.as_mut_ptr(), 0, 1); 75 s.assume_init() 76 } 77 } 78 } 79 } 80 81 module! { 82 type: BinderModule, 83 name: "rust_binder", 84 authors: ["Wedson Almeida Filho", "Alice Ryhl"], 85 description: "Android Binder", 86 license: "GPL", 87 } 88 89 use kernel::bindings::rust_binder_layout; 90 #[no_mangle] 91 static RUST_BINDER_LAYOUT: rust_binder_layout = rust_binder_layout { 92 t: transaction::TRANSACTION_LAYOUT, 93 p: process::PROCESS_LAYOUT, 94 n: node::NODE_LAYOUT, 95 }; 96 97 fn next_debug_id() -> usize { 98 static NEXT_DEBUG_ID: Atomic<usize> = Atomic::new(0); 99 100 NEXT_DEBUG_ID.fetch_add(1, Relaxed) 101 } 102 103 /// Provides a single place to write Binder return values via the 104 /// supplied `UserSliceWriter`. 105 pub(crate) struct BinderReturnWriter<'a> { 106 writer: UserSliceWriter, 107 thread: &'a Thread, 108 } 109 110 impl<'a> BinderReturnWriter<'a> { 111 fn new(writer: UserSliceWriter, thread: &'a Thread) -> Self { 112 BinderReturnWriter { writer, thread } 113 } 114 115 /// Write a return code back to user space. 116 /// Should be a `BR_` constant from [`defs`] e.g. [`defs::BR_TRANSACTION_COMPLETE`]. 117 fn write_code(&mut self, code: u32) -> Result { 118 crate::trace::trace_return(code); 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 pid: i32, 226 } 227 228 kernel::list::impl_list_arc_safe! { 229 impl ListArcSafe<0> for DeliverCode { untracked; } 230 } 231 232 impl DeliverCode { 233 fn new(code: u32, pid: i32) -> Self { 234 Self { 235 code, 236 skip: Atomic::new(false), 237 pid, 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, 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(Relaxed) { 257 writer.write_code(self.code)?; 258 } 259 Ok(true) 260 } 261 262 fn cancel(self: DArc<Self>) { 263 if !self.skip.load(Relaxed) { 264 binder_debug!( 265 pid = self.pid, 266 DeadTransaction, 267 "undelivered TRANSACTION_COMPLETE" 268 ); 269 } 270 } 271 272 fn should_sync_wakeup(&self) -> bool { 273 false 274 } 275 276 fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> { 277 seq_print!(m, "{}", prefix); 278 if self.skip.load(Relaxed) { 279 seq_print!(m, "(skipped) "); 280 } 281 if self.code == defs::BR_TRANSACTION_COMPLETE { 282 seq_print!(m, "transaction complete\n"); 283 } else { 284 seq_print!(m, "transaction error: {}\n", self.code); 285 } 286 Ok(()) 287 } 288 } 289 290 fn ptr_align(value: usize) -> Option<usize> { 291 let size = core::mem::size_of::<usize>() - 1; 292 Some(value.checked_add(size)? & !size) 293 } 294 295 // SAFETY: We call register in `init`. 296 static BINDER_SHRINKER: Shrinker = unsafe { Shrinker::new() }; 297 298 struct BinderModule { 299 _netlink: kernel::net::netlink::Registration, 300 } 301 302 impl kernel::Module for BinderModule { 303 fn init(_module: &'static kernel::ThisModule) -> Result<Self> { 304 // SAFETY: The module initializer never runs twice, so we only call this once. 305 unsafe { crate::context::CONTEXTS.init() }; 306 307 let netlink = crate::netlink::BINDER_NL_FAMILY.register()?; 308 BINDER_SHRINKER.register(c"android-binder")?; 309 310 // SAFETY: The module is being loaded, so we can initialize binderfs. 311 unsafe { kernel::error::to_result(binderfs::init_rust_binderfs())? }; 312 313 Ok(Self { _netlink: netlink }) 314 } 315 } 316 317 /// Makes the inner type Sync. 318 #[repr(transparent)] 319 pub struct AssertSync<T>(T); 320 // SAFETY: Used only to insert C bindings types into globals, which is safe. 321 unsafe impl<T> Sync for AssertSync<T> {} 322 323 /// File operations that rust_binderfs.c can use. 324 #[no_mangle] 325 #[used] 326 pub static rust_binder_fops: AssertSync<kernel::bindings::file_operations> = { 327 let ops = kernel::bindings::file_operations { 328 owner: THIS_MODULE.as_ptr(), 329 poll: Some(rust_binder_poll), 330 unlocked_ioctl: Some(rust_binder_ioctl), 331 compat_ioctl: bindings::compat_ptr_ioctl, 332 mmap: Some(rust_binder_mmap), 333 open: Some(rust_binder_open), 334 release: Some(rust_binder_release), 335 flush: Some(rust_binder_flush), 336 ..pin_init::zeroed() 337 }; 338 AssertSync(ops) 339 }; 340 341 /// # Safety 342 /// Only called by binderfs. 343 #[no_mangle] 344 unsafe extern "C" fn rust_binder_new_context( 345 name: *const kernel::ffi::c_char, 346 ) -> *mut kernel::ffi::c_void { 347 // SAFETY: The caller will always provide a valid c string here. 348 let name = unsafe { kernel::str::CStr::from_char_ptr(name) }; 349 match Context::new(name) { 350 Ok(ctx) => Arc::into_foreign(ctx), 351 Err(_err) => core::ptr::null_mut(), 352 } 353 } 354 355 /// # Safety 356 /// Only called by binderfs. 357 #[no_mangle] 358 unsafe extern "C" fn rust_binder_remove_context(device: *mut kernel::ffi::c_void) { 359 if !device.is_null() { 360 // SAFETY: The caller ensures that the `device` pointer came from a previous call to 361 // `rust_binder_new_device`. 362 let ctx = unsafe { Arc::<Context>::from_foreign(device) }; 363 ctx.deregister(); 364 drop(ctx); 365 } 366 } 367 368 /// # Safety 369 /// Only called by binderfs. 370 unsafe extern "C" fn rust_binder_open( 371 inode: *mut bindings::inode, 372 file_ptr: *mut bindings::file, 373 ) -> kernel::ffi::c_int { 374 // SAFETY: The `rust_binderfs.c` file ensures that `i_private` is set to a 375 // `struct binder_device`. 376 let device = unsafe { (*inode).i_private } as *const binderfs::binder_device; 377 378 assert!(!device.is_null()); 379 380 // SAFETY: The `rust_binderfs.c` file ensures that `device->ctx` holds a binder context when 381 // using the rust binder fops. 382 let ctx = unsafe { Arc::<Context>::borrow((*device).ctx) }; 383 384 // SAFETY: The caller provides a valid file pointer to a new `struct file`. 385 let file = unsafe { File::from_raw_file(file_ptr) }; 386 let process = match Process::open(ctx, file) { 387 Ok(process) => process, 388 Err(err) => return err.to_errno(), 389 }; 390 391 // SAFETY: This is an `inode` for a newly created binder file. 392 match unsafe { BinderfsProcFile::new(inode, process.task.pid()) } { 393 Ok(Some(file)) => process.inner.lock().binderfs_file = Some(file), 394 Ok(None) => { /* pid already exists */ } 395 Err(err) => return err.to_errno(), 396 } 397 398 // SAFETY: This file is associated with Rust binder, so we own the `private_data` field. 399 unsafe { (*file_ptr).private_data = process.into_foreign() }; 400 0 401 } 402 403 /// # Safety 404 /// Only called by binderfs. 405 unsafe extern "C" fn rust_binder_release( 406 _inode: *mut bindings::inode, 407 file: *mut bindings::file, 408 ) -> kernel::ffi::c_int { 409 // SAFETY: We previously set `private_data` in `rust_binder_open`. 410 let process = unsafe { Arc::<Process>::from_foreign((*file).private_data) }; 411 // SAFETY: The caller ensures that the file is valid. 412 let file = unsafe { File::from_raw_file(file) }; 413 Process::release(process, file); 414 0 415 } 416 417 /// # Safety 418 /// Only called by binderfs. 419 unsafe extern "C" fn rust_binder_ioctl( 420 file: *mut bindings::file, 421 cmd: kernel::ffi::c_uint, 422 arg: kernel::ffi::c_ulong, 423 ) -> kernel::ffi::c_long { 424 // SAFETY: We previously set `private_data` in `rust_binder_open`. 425 let f = unsafe { Arc::<Process>::borrow((*file).private_data) }; 426 // SAFETY: The caller ensures that the file is valid. 427 match Process::ioctl(f, unsafe { File::from_raw_file(file) }, cmd, arg) { 428 Ok(()) => 0, 429 Err(err) => err.to_errno() as isize, 430 } 431 } 432 433 /// # Safety 434 /// Only called by binderfs. 435 unsafe extern "C" fn rust_binder_mmap( 436 file: *mut bindings::file, 437 vma: *mut bindings::vm_area_struct, 438 ) -> kernel::ffi::c_int { 439 // SAFETY: We previously set `private_data` in `rust_binder_open`. 440 let f = unsafe { Arc::<Process>::borrow((*file).private_data) }; 441 // SAFETY: The caller ensures that the vma is valid. 442 let area = unsafe { kernel::mm::virt::VmaNew::from_raw(vma) }; 443 // SAFETY: The caller ensures that the file is valid. 444 match Process::mmap(f, unsafe { File::from_raw_file(file) }, area) { 445 Ok(()) => 0, 446 Err(err) => err.to_errno(), 447 } 448 } 449 450 /// # Safety 451 /// Only called by binderfs. 452 unsafe extern "C" fn rust_binder_poll( 453 file: *mut bindings::file, 454 wait: *mut bindings::poll_table_struct, 455 ) -> bindings::__poll_t { 456 // SAFETY: We previously set `private_data` in `rust_binder_open`. 457 let f = unsafe { Arc::<Process>::borrow((*file).private_data) }; 458 // SAFETY: The caller ensures that the file is valid. 459 let fileref = unsafe { File::from_raw_file(file) }; 460 // SAFETY: The caller ensures that the `PollTable` is valid. 461 match Process::poll(f, fileref, unsafe { PollTable::from_raw(wait) }) { 462 Ok(v) => v, 463 Err(_) => bindings::POLLERR, 464 } 465 } 466 467 /// # Safety 468 /// Only called by binderfs. 469 unsafe extern "C" fn rust_binder_flush( 470 file: *mut bindings::file, 471 _id: bindings::fl_owner_t, 472 ) -> kernel::ffi::c_int { 473 // SAFETY: We previously set `private_data` in `rust_binder_open`. 474 let f = unsafe { Arc::<Process>::borrow((*file).private_data) }; 475 match Process::flush(f) { 476 Ok(()) => 0, 477 Err(err) => err.to_errno(), 478 } 479 } 480 481 /// # Safety 482 /// Only called by binderfs. 483 #[no_mangle] 484 unsafe extern "C" fn rust_binder_stats_show( 485 ptr: *mut seq_file, 486 _: *mut kernel::ffi::c_void, 487 ) -> kernel::ffi::c_int { 488 // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which 489 // this method is called. 490 let m = unsafe { SeqFile::from_raw(ptr) }; 491 if let Err(err) = rust_binder_stats_show_impl(m) { 492 seq_print!(m, "failed to generate state: {:?}\n", err); 493 } 494 0 495 } 496 497 /// # Safety 498 /// Only called by binderfs. 499 #[no_mangle] 500 unsafe extern "C" fn rust_binder_state_show( 501 ptr: *mut seq_file, 502 _: *mut kernel::ffi::c_void, 503 ) -> kernel::ffi::c_int { 504 // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which 505 // this method is called. 506 let m = unsafe { SeqFile::from_raw(ptr) }; 507 if let Err(err) = rust_binder_state_show_impl(m) { 508 seq_print!(m, "failed to generate state: {:?}\n", err); 509 } 510 0 511 } 512 513 /// # Safety 514 /// Only called by binderfs. 515 #[no_mangle] 516 unsafe extern "C" fn rust_binder_proc_show( 517 ptr: *mut seq_file, 518 _: *mut kernel::ffi::c_void, 519 ) -> kernel::ffi::c_int { 520 // SAFETY: Accessing the private field of `seq_file` is okay. 521 let pid = unsafe { (*ptr).private }.addr() as Pid; 522 // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which 523 // this method is called. 524 let m = unsafe { SeqFile::from_raw(ptr) }; 525 if let Err(err) = rust_binder_proc_show_impl(m, pid) { 526 seq_print!(m, "failed to generate state: {:?}\n", err); 527 } 528 0 529 } 530 531 /// # Safety 532 /// Only called by binderfs. 533 #[no_mangle] 534 unsafe extern "C" fn rust_binder_transactions_show( 535 ptr: *mut seq_file, 536 _: *mut kernel::ffi::c_void, 537 ) -> kernel::ffi::c_int { 538 // SAFETY: The caller ensures that the pointer is valid and exclusive for the duration in which 539 // this method is called. 540 let m = unsafe { SeqFile::from_raw(ptr) }; 541 if let Err(err) = rust_binder_transactions_show_impl(m) { 542 seq_print!(m, "failed to generate state: {:?}\n", err); 543 } 544 0 545 } 546 547 fn rust_binder_transactions_show_impl(m: &SeqFile) -> Result<()> { 548 seq_print!(m, "binder transactions:\n"); 549 let contexts = context::get_all_contexts()?; 550 for ctx in contexts { 551 let procs = ctx.get_all_procs()?; 552 for proc in procs { 553 proc.debug_print(m, &ctx, false)?; 554 seq_print!(m, "\n"); 555 } 556 } 557 Ok(()) 558 } 559 560 fn rust_binder_stats_show_impl(m: &SeqFile) -> Result<()> { 561 seq_print!(m, "binder stats:\n"); 562 stats::GLOBAL_STATS.debug_print("", m); 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_stats(m, &ctx)?; 568 seq_print!(m, "\n"); 569 } 570 } 571 Ok(()) 572 } 573 574 fn rust_binder_state_show_impl(m: &SeqFile) -> Result<()> { 575 seq_print!(m, "binder state:\n"); 576 let contexts = context::get_all_contexts()?; 577 for ctx in contexts { 578 let procs = ctx.get_all_procs()?; 579 for proc in procs { 580 proc.debug_print(m, &ctx, true)?; 581 seq_print!(m, "\n"); 582 } 583 } 584 Ok(()) 585 } 586 587 fn rust_binder_proc_show_impl(m: &SeqFile, pid: Pid) -> Result<()> { 588 seq_print!(m, "binder proc state:\n"); 589 let contexts = context::get_all_contexts()?; 590 for ctx in contexts { 591 let procs = ctx.get_procs_with_pid(pid)?; 592 for proc in procs { 593 proc.debug_print(m, &ctx, true)?; 594 seq_print!(m, "\n"); 595 } 596 } 597 Ok(()) 598 } 599 600 struct BinderfsProcFile(NonNull<bindings::dentry>); 601 602 // SAFETY: Safe to drop any thread. 603 unsafe impl Send for BinderfsProcFile {} 604 605 impl BinderfsProcFile { 606 /// # Safety 607 /// 608 /// Takes an inode from a newly created binder file. 609 unsafe fn new(nodp: *mut bindings::inode, pid: i32) -> Result<Option<Self>> { 610 // SAFETY: The caller passes an `inode` for a newly created binder file. 611 let dentry = unsafe { binderfs::rust_binderfs_create_proc_file(nodp, pid) }; 612 match kernel::error::from_err_ptr(dentry) { 613 Ok(dentry) => Ok(NonNull::new(dentry).map(Self)), 614 Err(err) if err == EEXIST => Ok(None), 615 Err(err) => Err(err), 616 } 617 } 618 } 619 620 impl Drop for BinderfsProcFile { 621 fn drop(&mut self) { 622 // SAFETY: This is a dentry from `rust_binderfs_remove_file` that has not been deleted yet. 623 unsafe { binderfs::rust_binderfs_remove_file(self.0.as_ptr()) }; 624 } 625 } 626