1 // SPDX-License-Identifier: GPL-2.0 2 3 // Copyright (C) 2025 Google LLC. 4 5 //! This module defines the `Thread` type, which represents a userspace thread that is using 6 //! binder. 7 //! 8 //! The `Process` object stores all of the threads in an rb tree. 9 10 use kernel::{ 11 bindings, 12 fs::LocalFile, 13 list::{AtomicTracker, List, ListArc, ListLinks, TryNewListArc}, 14 prelude::*, 15 security, 16 seq_file::SeqFile, 17 seq_print, 18 sync::atomic::{ordering::Relaxed, Atomic}, 19 sync::{aref::ARef, Arc, CondVar, SpinLock}, 20 task::Task, 21 uaccess::{UserPtr, UserSlice, UserSliceReader}, 22 uapi, 23 }; 24 25 use crate::{ 26 allocation::{Allocation, AllocationView, BinderObject, BinderObjectRef, NewAllocation}, 27 defs::*, 28 error::BinderResult, 29 process::{GetWorkOrRegister, Process}, 30 ptr_align, 31 stats::GLOBAL_STATS, 32 transaction::{Transaction, TransactionInfo}, 33 BinderReturnWriter, DArc, DLArc, DTRWrap, DeliverCode, DeliverToRead, 34 }; 35 36 use core::mem::size_of; 37 38 fn is_aligned(value: usize, to: usize) -> bool { 39 value % to == 0 40 } 41 42 /// Stores the layout of the scatter-gather entries. This is used during the `translate_objects` 43 /// call and is discarded when it returns. 44 struct ScatterGatherState { 45 /// A struct that tracks the amount of unused buffer space. 46 unused_buffer_space: UnusedBufferSpace, 47 /// Scatter-gather entries to copy. 48 sg_entries: KVec<ScatterGatherEntry>, 49 /// Indexes into `sg_entries` corresponding to the last binder_buffer_object that 50 /// was processed and all of its ancestors. The array is in sorted order. 51 ancestors: KVec<usize>, 52 } 53 54 /// This entry specifies an additional buffer that should be copied using the scatter-gather 55 /// mechanism. 56 struct ScatterGatherEntry { 57 /// The index in the offset array of the BINDER_TYPE_PTR that this entry originates from. 58 obj_index: usize, 59 /// Offset in target buffer. 60 offset: usize, 61 /// User address in source buffer. 62 sender_uaddr: usize, 63 /// Number of bytes to copy. 64 length: usize, 65 /// The minimum offset of the next fixup in this buffer. 66 fixup_min_offset: usize, 67 /// The offsets within this buffer that contain pointers which should be translated. 68 pointer_fixups: KVec<PointerFixupEntry>, 69 } 70 71 /// This entry specifies that a fixup should happen at `target_offset` of the 72 /// buffer. 73 enum PointerFixupEntry { 74 /// A fixup for a `binder_buffer_object`. 75 Fixup { 76 /// The translated pointer to write. 77 pointer_value: u64, 78 /// The offset at which the value should be written. The offset is relative 79 /// to the original buffer. 80 target_offset: usize, 81 }, 82 /// A skip for a `binder_fd_array_object`. 83 Skip { 84 /// The number of bytes to skip. 85 skip: usize, 86 /// The offset at which the skip should happen. The offset is relative 87 /// to the original buffer. 88 target_offset: usize, 89 }, 90 } 91 92 /// Return type of `apply_and_validate_fixup_in_parent`. 93 struct ParentFixupInfo { 94 /// The index of the parent buffer in `sg_entries`. 95 parent_sg_index: usize, 96 /// The number of ancestors of the buffer. 97 /// 98 /// The buffer is considered an ancestor of itself, so this is always at 99 /// least one. 100 num_ancestors: usize, 101 /// New value of `fixup_min_offset` if this fixup is applied. 102 new_min_offset: usize, 103 /// The offset of the fixup in the target buffer. 104 target_offset: usize, 105 } 106 107 impl ScatterGatherState { 108 /// Called when a `binder_buffer_object` or `binder_fd_array_object` tries 109 /// to access a region in its parent buffer. These accesses have various 110 /// restrictions, which this method verifies. 111 /// 112 /// The `parent_offset` and `length` arguments describe the offset and 113 /// length of the access in the parent buffer. 114 /// 115 /// # Detailed restrictions 116 /// 117 /// Obviously the fixup must be in-bounds for the parent buffer. 118 /// 119 /// For safety reasons, we only allow fixups inside a buffer to happen 120 /// at increasing offsets; additionally, we only allow fixup on the last 121 /// buffer object that was verified, or one of its parents. 122 /// 123 /// Example of what is allowed: 124 /// 125 /// A 126 /// B (parent = A, offset = 0) 127 /// C (parent = A, offset = 16) 128 /// D (parent = C, offset = 0) 129 /// E (parent = A, offset = 32) // min_offset is 16 (C.parent_offset) 130 /// 131 /// Examples of what is not allowed: 132 /// 133 /// Decreasing offsets within the same parent: 134 /// A 135 /// C (parent = A, offset = 16) 136 /// B (parent = A, offset = 0) // decreasing offset within A 137 /// 138 /// Arcerring to a parent that wasn't the last object or any of its parents: 139 /// A 140 /// B (parent = A, offset = 0) 141 /// C (parent = A, offset = 0) 142 /// C (parent = A, offset = 16) 143 /// D (parent = B, offset = 0) // B is not A or any of A's parents 144 fn validate_parent_fixup( 145 &self, 146 parent: usize, 147 parent_offset: usize, 148 length: usize, 149 ) -> Result<ParentFixupInfo> { 150 // Using `position` would also be correct, but `rposition` avoids 151 // quadratic running times. 152 let ancestors_i = self 153 .ancestors 154 .iter() 155 .copied() 156 .rposition(|sg_idx| self.sg_entries[sg_idx].obj_index == parent) 157 .ok_or(EINVAL)?; 158 let sg_idx = self.ancestors[ancestors_i]; 159 let sg_entry = match self.sg_entries.get(sg_idx) { 160 Some(sg_entry) => sg_entry, 161 None => { 162 pr_err!( 163 "self.ancestors[{}] is {}, but self.sg_entries.len() is {}", 164 ancestors_i, 165 sg_idx, 166 self.sg_entries.len() 167 ); 168 return Err(EINVAL); 169 } 170 }; 171 if sg_entry.fixup_min_offset > parent_offset { 172 pr_warn!( 173 "validate_parent_fixup: fixup_min_offset={}, parent_offset={}", 174 sg_entry.fixup_min_offset, 175 parent_offset 176 ); 177 return Err(EINVAL); 178 } 179 let new_min_offset = parent_offset.checked_add(length).ok_or(EINVAL)?; 180 if new_min_offset > sg_entry.length { 181 pr_warn!( 182 "validate_parent_fixup: new_min_offset={}, sg_entry.length={}", 183 new_min_offset, 184 sg_entry.length 185 ); 186 return Err(EINVAL); 187 } 188 let target_offset = sg_entry.offset.checked_add(parent_offset).ok_or(EINVAL)?; 189 // The `ancestors_i + 1` operation can't overflow since the output of the addition is at 190 // most `self.ancestors.len()`, which also fits in a usize. 191 Ok(ParentFixupInfo { 192 parent_sg_index: sg_idx, 193 num_ancestors: ancestors_i + 1, 194 new_min_offset, 195 target_offset, 196 }) 197 } 198 } 199 200 /// Keeps track of how much unused buffer space is left. The initial amount is the number of bytes 201 /// requested by the user using the `buffers_size` field of `binder_transaction_data_sg`. Each time 202 /// we translate an object of type `BINDER_TYPE_PTR`, some of the unused buffer space is consumed. 203 struct UnusedBufferSpace { 204 /// The start of the remaining space. 205 offset: usize, 206 /// The end of the remaining space. 207 limit: usize, 208 } 209 impl UnusedBufferSpace { 210 /// Claim the next `size` bytes from the unused buffer space. The offset for the claimed chunk 211 /// into the buffer is returned. 212 fn claim_next(&mut self, size: usize) -> Result<usize> { 213 // We require every chunk to be aligned. 214 let size = ptr_align(size).ok_or(EINVAL)?; 215 let new_offset = self.offset.checked_add(size).ok_or(EINVAL)?; 216 217 if new_offset <= self.limit { 218 let offset = self.offset; 219 self.offset = new_offset; 220 Ok(offset) 221 } else { 222 Err(EINVAL) 223 } 224 } 225 } 226 227 #[must_use] 228 pub(crate) enum PushWorkRes { 229 Ok, 230 OkNotifyPoll, 231 FailedDead(DLArc<dyn DeliverToRead>), 232 } 233 234 impl PushWorkRes { 235 fn is_ok(&self) -> bool { 236 match self { 237 PushWorkRes::Ok => true, 238 PushWorkRes::OkNotifyPoll => true, 239 PushWorkRes::FailedDead(_) => false, 240 } 241 } 242 } 243 244 /// The fields of `Thread` protected by the spinlock. 245 struct InnerThread { 246 /// Determines the looper state of the thread. It is a bit-wise combination of the constants 247 /// prefixed with `LOOPER_`. 248 looper_flags: u32, 249 250 /// Determines whether the looper should return. 251 looper_need_return: bool, 252 253 /// Determines if thread is dead. 254 is_dead: bool, 255 256 /// Work item used to deliver error codes to the thread that started a transaction. Stored here 257 /// so that it can be reused. 258 reply_work: DArc<ThreadError>, 259 260 /// Work item used to deliver error codes to the current thread. Stored here so that it can be 261 /// reused. 262 return_work: DArc<ThreadError>, 263 264 /// Determines whether the work list below should be processed. When set to false, `work_list` 265 /// is treated as if it were empty. 266 process_work_list: bool, 267 /// List of work items to deliver to userspace. 268 work_list: List<DTRWrap<dyn DeliverToRead>>, 269 current_transaction: Option<DArc<Transaction>>, 270 271 /// Extended error information for this thread. 272 extended_error: ExtendedError, 273 } 274 275 const LOOPER_REGISTERED: u32 = 0x01; 276 const LOOPER_ENTERED: u32 = 0x02; 277 const LOOPER_EXITED: u32 = 0x04; 278 const LOOPER_INVALID: u32 = 0x08; 279 const LOOPER_WAITING: u32 = 0x10; 280 const LOOPER_WAITING_PROC: u32 = 0x20; 281 const LOOPER_POLL: u32 = 0x40; 282 283 impl InnerThread { 284 fn new(pid: i32) -> Result<Self> { 285 fn next_err_id() -> u32 { 286 static EE_ID: Atomic<u32> = Atomic::new(0); 287 EE_ID.fetch_add(1, Relaxed) 288 } 289 290 Ok(Self { 291 looper_flags: 0, 292 looper_need_return: false, 293 is_dead: false, 294 process_work_list: false, 295 reply_work: ThreadError::try_new(pid)?, 296 return_work: ThreadError::try_new(pid)?, 297 work_list: List::new(), 298 current_transaction: None, 299 extended_error: ExtendedError::new(next_err_id(), BR_OK, 0), 300 }) 301 } 302 303 fn pop_work(&mut self) -> Option<DLArc<dyn DeliverToRead>> { 304 if !self.process_work_list { 305 return None; 306 } 307 308 let ret = self.work_list.pop_front(); 309 self.process_work_list = !self.work_list.is_empty(); 310 ret 311 } 312 313 fn push_work(&mut self, work: DLArc<dyn DeliverToRead>) -> PushWorkRes { 314 if self.is_dead { 315 return PushWorkRes::FailedDead(work); 316 } 317 self.work_list.push_back(work); 318 self.process_work_list = true; 319 if self.looper_flags & LOOPER_POLL != 0 { 320 PushWorkRes::OkNotifyPoll 321 } else { 322 PushWorkRes::Ok 323 } 324 } 325 326 fn push_reply_work(&mut self, code: u32) -> PushWorkRes { 327 if let Ok(work) = ListArc::try_from_arc(self.reply_work.clone()) { 328 work.set_error_code(code); 329 self.push_work(work) 330 } else { 331 pr_warn!("Thread reply work is already in use."); 332 PushWorkRes::Ok 333 } 334 } 335 336 fn push_return_work(&mut self, reply: u32) { 337 if let Ok(work) = ListArc::try_from_arc(self.return_work.clone()) { 338 work.set_error_code(reply); 339 // Not notifying: Reply to current thread. 340 let _ = self.push_work(work); 341 } else { 342 pr_warn!("Thread return work is already in use."); 343 } 344 } 345 346 /// Used to push work items that do not need to be processed immediately and can wait until the 347 /// thread gets another work item. 348 fn push_work_deferred(&mut self, work: DLArc<dyn DeliverToRead>) { 349 self.work_list.push_back(work); 350 } 351 352 /// Fetches the transaction this thread can reply to. If the thread has a pending transaction 353 /// (that it could respond to) but it has also issued a transaction, it must first wait for the 354 /// previously-issued transaction to complete. 355 /// 356 /// The `thread` parameter should be the thread containing this `ThreadInner`. 357 fn pop_transaction_to_reply(&mut self, thread: &Thread) -> Result<DArc<Transaction>> { 358 let transaction = self.current_transaction.take().ok_or(EINVAL)?; 359 if core::ptr::eq(thread, transaction.from.as_ref()) { 360 self.current_transaction = Some(transaction); 361 return Err(EINVAL); 362 } 363 // Find a new current transaction for this thread. 364 self.current_transaction = transaction.find_from(thread).cloned(); 365 Ok(transaction) 366 } 367 368 fn pop_transaction_replied(&mut self, transaction: &DArc<Transaction>) -> bool { 369 match self.current_transaction.take() { 370 None => false, 371 Some(old) => { 372 if !Arc::ptr_eq(transaction, &old) { 373 self.current_transaction = Some(old); 374 return false; 375 } 376 self.current_transaction = old.clone_next(); 377 true 378 } 379 } 380 } 381 382 fn looper_enter(&mut self) { 383 self.looper_flags |= LOOPER_ENTERED; 384 if self.looper_flags & LOOPER_REGISTERED != 0 { 385 self.looper_flags |= LOOPER_INVALID; 386 } 387 } 388 389 fn looper_register(&mut self, valid: bool) { 390 self.looper_flags |= LOOPER_REGISTERED; 391 if !valid || self.looper_flags & LOOPER_ENTERED != 0 { 392 self.looper_flags |= LOOPER_INVALID; 393 } 394 } 395 396 fn looper_exit(&mut self) { 397 self.looper_flags |= LOOPER_EXITED; 398 } 399 400 /// Determines whether the thread is part of a pool, i.e., if it is a looper. 401 fn is_looper(&self) -> bool { 402 self.looper_flags & (LOOPER_ENTERED | LOOPER_REGISTERED) != 0 403 } 404 405 /// Determines whether the thread should attempt to fetch work items from the process queue. 406 /// This is generally case when the thread is registered as a looper and not part of a 407 /// transaction stack. But if there is local work, we want to return to userspace before we 408 /// deliver any remote work. 409 fn should_use_process_work_queue(&self) -> bool { 410 self.current_transaction.is_none() && !self.process_work_list && self.is_looper() 411 } 412 413 fn poll(&mut self) -> u32 { 414 self.looper_flags |= LOOPER_POLL; 415 if self.process_work_list || self.looper_need_return { 416 bindings::POLLIN 417 } else { 418 0 419 } 420 } 421 } 422 423 /// This represents a thread that's used with binder. 424 #[pin_data] 425 pub(crate) struct Thread { 426 pub(crate) id: i32, 427 pub(crate) process: Arc<Process>, 428 pub(crate) task: ARef<Task>, 429 #[pin] 430 inner: SpinLock<InnerThread>, 431 #[pin] 432 work_condvar: CondVar, 433 /// Used to insert this thread into the process' `ready_threads` list. 434 /// 435 /// INVARIANT: May never be used for any other list than the `self.process.ready_threads`. 436 #[pin] 437 links: ListLinks, 438 #[pin] 439 links_track: AtomicTracker, 440 } 441 442 kernel::list::impl_list_arc_safe! { 443 impl ListArcSafe<0> for Thread { 444 tracked_by links_track: AtomicTracker; 445 } 446 } 447 kernel::list::impl_list_item! { 448 impl ListItem<0> for Thread { 449 using ListLinks { self.links }; 450 } 451 } 452 453 impl Thread { 454 pub(crate) fn new(id: i32, process: Arc<Process>) -> Result<Arc<Self>> { 455 let inner = InnerThread::new(process.task.pid())?; 456 457 Arc::pin_init( 458 try_pin_init!(Thread { 459 id, 460 process, 461 task: ARef::from(&**kernel::current!()), 462 inner <- kernel::new_spinlock!(inner, "Thread::inner"), 463 work_condvar <- kernel::new_condvar!("Thread::work_condvar"), 464 links <- ListLinks::new(), 465 links_track <- AtomicTracker::new(), 466 }), 467 GFP_KERNEL, 468 ) 469 } 470 471 #[inline(never)] 472 pub(crate) fn debug_print(self: &Arc<Self>, m: &SeqFile, print_all: bool) -> Result<()> { 473 let inner = self.inner.lock(); 474 475 if print_all || inner.current_transaction.is_some() || !inner.work_list.is_empty() { 476 seq_print!( 477 m, 478 " thread {}: l {:02x} need_return {}\n", 479 self.id, 480 inner.looper_flags, 481 inner.looper_need_return, 482 ); 483 } 484 485 let mut t_opt = inner.current_transaction.as_ref(); 486 while let Some(t) = t_opt { 487 if Arc::ptr_eq(&t.from, self) { 488 t.debug_print_inner(m, " outgoing transaction "); 489 t_opt = t.from_parent.as_ref(); 490 } else if Arc::ptr_eq(&t.to, &self.process) { 491 t.debug_print_inner(m, " incoming transaction "); 492 t_opt = t.find_from(self); 493 } else { 494 t.debug_print_inner(m, " bad transaction "); 495 t_opt = None; 496 } 497 } 498 499 for work in &inner.work_list { 500 work.debug_print(m, " ", " pending transaction ")?; 501 } 502 Ok(()) 503 } 504 505 pub(crate) fn clear_extended_error(&self, debug_id: usize) { 506 self.inner.lock().extended_error = ExtendedError::new(debug_id as u32, BR_OK, 0); 507 } 508 509 pub(crate) fn get_extended_error(&self, data: UserSlice) -> Result { 510 let mut writer = data.writer(); 511 let mut inner = self.inner.lock(); 512 let ee = inner.extended_error; 513 inner.extended_error = ExtendedError::new(0, BR_OK, 0); 514 drop(inner); 515 writer.write(&ee)?; 516 Ok(()) 517 } 518 519 pub(crate) fn set_current_transaction(&self, transaction: DArc<Transaction>) { 520 self.inner.lock().current_transaction = Some(transaction); 521 } 522 523 pub(crate) fn has_current_transaction(&self) -> bool { 524 self.inner.lock().current_transaction.is_some() 525 } 526 527 /// Attempts to fetch a work item from the thread-local queue. The behaviour if the queue is 528 /// empty depends on `wait`: if it is true, the function waits for some work to be queued (or a 529 /// signal); otherwise it returns indicating that none is available. 530 // #[export_name] is a temporary workaround so that ps output does not become unreadable from 531 // mangled symbol names. 532 #[export_name = "rust_binder_waitlcl"] 533 fn get_work_local(self: &Arc<Self>, wait: bool) -> Result<Option<DLArc<dyn DeliverToRead>>> { 534 { 535 let mut inner = self.inner.lock(); 536 if inner.looper_need_return { 537 return Ok(inner.pop_work()); 538 } 539 } 540 541 // Try once if the caller does not want to wait. 542 if !wait { 543 return self.inner.lock().pop_work().ok_or(EAGAIN).map(Some); 544 } 545 546 // Loop waiting only on the local queue (i.e., not registering with the process queue). 547 let mut inner = self.inner.lock(); 548 loop { 549 if let Some(work) = inner.pop_work() { 550 return Ok(Some(work)); 551 } 552 553 inner.looper_flags |= LOOPER_WAITING; 554 let signal_pending = self.work_condvar.wait_interruptible_freezable(&mut inner); 555 inner.looper_flags &= !LOOPER_WAITING; 556 557 if signal_pending { 558 return Err(EINTR); 559 } 560 if inner.looper_need_return { 561 return Ok(None); 562 } 563 } 564 } 565 566 /// Attempts to fetch a work item from the thread-local queue, falling back to the process-wide 567 /// queue if none is available locally. 568 /// 569 /// This must only be called when the thread is not participating in a transaction chain. If it 570 /// is, the local version (`get_work_local`) should be used instead. 571 // #[export_name] is a temporary workaround so that ps output does not become unreadable from 572 // mangled symbol names. 573 #[export_name = "rust_binder_wait"] 574 fn get_work(self: &Arc<Self>, wait: bool) -> Result<Option<DLArc<dyn DeliverToRead>>> { 575 // Try to get work from the thread's work queue, using only a local lock. 576 { 577 let mut inner = self.inner.lock(); 578 if let Some(work) = inner.pop_work() { 579 return Ok(Some(work)); 580 } 581 if inner.looper_need_return { 582 drop(inner); 583 return Ok(self.process.get_work()); 584 } 585 } 586 587 // If the caller doesn't want to wait, try to grab work from the process queue. 588 // 589 // We know nothing will have been queued directly to the thread queue because it is not in 590 // a transaction and it is not in the process' ready list. 591 if !wait { 592 return self.process.get_work().ok_or(EAGAIN).map(Some); 593 } 594 595 // Get work from the process queue. If none is available, atomically register as ready. 596 let reg = match self.process.get_work_or_register(self) { 597 GetWorkOrRegister::Work(work) => return Ok(Some(work)), 598 GetWorkOrRegister::Register(reg) => reg, 599 }; 600 601 let mut inner = self.inner.lock(); 602 loop { 603 if let Some(work) = inner.pop_work() { 604 return Ok(Some(work)); 605 } 606 607 inner.looper_flags |= LOOPER_WAITING | LOOPER_WAITING_PROC; 608 let signal_pending = self.work_condvar.wait_interruptible_freezable(&mut inner); 609 inner.looper_flags &= !(LOOPER_WAITING | LOOPER_WAITING_PROC); 610 611 if signal_pending || inner.looper_need_return { 612 // We need to return now. We need to pull the thread off the list of ready threads 613 // (by dropping `reg`), then check the state again after it's off the list to 614 // ensure that something was not queued in the meantime. If something has been 615 // queued, we just return it (instead of the error). 616 drop(inner); 617 drop(reg); 618 619 let res = match self.inner.lock().pop_work() { 620 Some(work) => Ok(Some(work)), 621 None if signal_pending => Err(EINTR), 622 None => Ok(None), 623 }; 624 return res; 625 } 626 } 627 } 628 629 /// Push the provided work item to be delivered to user space via this thread. 630 /// 631 /// Returns whether the item was successfully pushed. This can only fail if the thread is dead. 632 pub(crate) fn push_work(&self, work: DLArc<dyn DeliverToRead>) -> PushWorkRes { 633 let sync = work.should_sync_wakeup(); 634 self.push_work_inner(work, sync) 635 } 636 637 pub(crate) fn push_work_inner( 638 &self, 639 work: DLArc<dyn DeliverToRead>, 640 sync: bool, 641 ) -> PushWorkRes { 642 let res = self.inner.lock().push_work(work); 643 644 if res.is_ok() { 645 if sync { 646 self.work_condvar.notify_sync(); 647 } else { 648 self.work_condvar.notify_one(); 649 } 650 } 651 652 res 653 } 654 655 /// Attempts to push to given work item to the thread if it's a looper thread (i.e., if it's 656 /// part of a thread pool) and is alive. Otherwise, push the work item to the process instead. 657 pub(crate) fn push_work_if_looper(&self, work: DLArc<dyn DeliverToRead>) -> BinderResult { 658 let mut inner = self.inner.lock(); 659 if inner.is_looper() && !inner.is_dead { 660 // Not notifying: Reply to current thread. 661 let _ = inner.push_work(work); 662 Ok(()) 663 } else { 664 drop(inner); 665 self.process.push_work(work) 666 } 667 } 668 669 pub(crate) fn push_work_deferred(&self, work: DLArc<dyn DeliverToRead>) { 670 self.inner.lock().push_work_deferred(work); 671 } 672 673 pub(crate) fn push_return_work(&self, reply: u32) { 674 self.inner.lock().push_return_work(reply); 675 } 676 677 fn translate_object( 678 &self, 679 obj_index: usize, 680 offset: usize, 681 object: BinderObjectRef<'_>, 682 view: &mut AllocationView<'_>, 683 allow_fds: bool, 684 sg_state: &mut ScatterGatherState, 685 ) -> BinderResult { 686 match object { 687 BinderObjectRef::Binder(obj) => { 688 let strong = obj.hdr.type_ == BINDER_TYPE_BINDER; 689 // SAFETY: `binder` is a `binder_uintptr_t`; any bit pattern is a valid 690 // representation. 691 let ptr = unsafe { obj.__bindgen_anon_1.binder }; 692 let cookie = obj.cookie; 693 let flags = obj.flags; 694 let node = self 695 .process 696 .as_arc_borrow() 697 .get_node(ptr, cookie, flags, strong, self)?; 698 security::binder_transfer_binder(&self.process.cred, &view.alloc.process.cred)?; 699 view.transfer_binder_object(offset, obj, strong, node)?; 700 } 701 BinderObjectRef::Handle(obj) => { 702 let strong = obj.hdr.type_ == BINDER_TYPE_HANDLE; 703 // SAFETY: `handle` is a `u32`; any bit pattern is a valid representation. 704 let handle = unsafe { obj.__bindgen_anon_1.handle }; 705 let node = self.process.get_node_from_handle(handle, strong)?; 706 security::binder_transfer_binder(&self.process.cred, &view.alloc.process.cred)?; 707 view.transfer_binder_object(offset, obj, strong, node)?; 708 } 709 BinderObjectRef::Fd(obj) => { 710 if !allow_fds { 711 return Err(EPERM.into()); 712 } 713 714 // SAFETY: `fd` is a `u32`; any bit pattern is a valid representation. 715 let fd = unsafe { obj.__bindgen_anon_1.fd }; 716 let file = LocalFile::fget(fd)?; 717 // SAFETY: The binder driver never calls `fdget_pos` and this code runs from an 718 // ioctl, so there are no active calls to `fdget_pos` on this thread. 719 let file = unsafe { LocalFile::assume_no_fdget_pos(file) }; 720 security::binder_transfer_file( 721 &self.process.cred, 722 &view.alloc.process.cred, 723 &file, 724 )?; 725 726 let mut obj_write = BinderFdObject::default(); 727 obj_write.hdr.type_ = BINDER_TYPE_FD; 728 // This will be overwritten with the actual fd when the transaction is received. 729 obj_write.__bindgen_anon_1.fd = u32::MAX; 730 obj_write.cookie = obj.cookie; 731 view.write::<BinderFdObject>(offset, &obj_write)?; 732 733 const FD_FIELD_OFFSET: usize = 734 core::mem::offset_of!(uapi::binder_fd_object, __bindgen_anon_1.fd); 735 736 let field_offset = offset + FD_FIELD_OFFSET; 737 crate::trace::trace_transaction_fd_send(view.alloc.debug_id, fd, field_offset); 738 739 view.alloc.info_add_fd(file, field_offset, false)?; 740 } 741 BinderObjectRef::Ptr(obj) => { 742 let obj_length = obj.length.try_into().map_err(|_| EINVAL)?; 743 let alloc_offset = match sg_state.unused_buffer_space.claim_next(obj_length) { 744 Ok(alloc_offset) => alloc_offset, 745 Err(err) => { 746 binder_debug!( 747 UserError, 748 "failed to claim space for a BINDER_TYPE_PTR (offset: {}, limit: {}, size: {})", 749 sg_state.unused_buffer_space.offset, 750 sg_state.unused_buffer_space.limit, 751 obj_length 752 ); 753 return Err(err.into()); 754 } 755 }; 756 757 let sg_state_idx = sg_state.sg_entries.len(); 758 sg_state.sg_entries.push( 759 ScatterGatherEntry { 760 obj_index, 761 offset: alloc_offset, 762 sender_uaddr: obj.buffer as usize, 763 length: obj_length, 764 pointer_fixups: KVec::new(), 765 fixup_min_offset: 0, 766 }, 767 GFP_KERNEL, 768 )?; 769 770 let buffer_ptr_in_user_space = (view.alloc.ptr + alloc_offset) as u64; 771 772 if obj.flags & uapi::BINDER_BUFFER_FLAG_HAS_PARENT == 0 { 773 sg_state.ancestors.clear(); 774 sg_state.ancestors.push(sg_state_idx, GFP_KERNEL)?; 775 } else { 776 // Another buffer also has a pointer to this buffer, and we need to fixup that 777 // pointer too. 778 779 let parent_index = usize::try_from(obj.parent).map_err(|_| EINVAL)?; 780 let parent_offset = usize::try_from(obj.parent_offset).map_err(|_| EINVAL)?; 781 782 let info = sg_state.validate_parent_fixup( 783 parent_index, 784 parent_offset, 785 size_of::<u64>(), 786 )?; 787 788 sg_state.ancestors.truncate(info.num_ancestors); 789 sg_state.ancestors.push(sg_state_idx, GFP_KERNEL)?; 790 791 let parent_entry = match sg_state.sg_entries.get_mut(info.parent_sg_index) { 792 Some(parent_entry) => parent_entry, 793 None => { 794 pr_err!( 795 "validate_parent_fixup returned index out of bounds for sg.entries" 796 ); 797 return Err(EINVAL.into()); 798 } 799 }; 800 801 parent_entry.fixup_min_offset = info.new_min_offset; 802 parent_entry.pointer_fixups.push( 803 PointerFixupEntry::Fixup { 804 pointer_value: buffer_ptr_in_user_space, 805 target_offset: info.target_offset, 806 }, 807 GFP_KERNEL, 808 )?; 809 } 810 811 let mut obj_write = BinderBufferObject::default(); 812 obj_write.hdr.type_ = BINDER_TYPE_PTR; 813 obj_write.flags = obj.flags; 814 obj_write.buffer = buffer_ptr_in_user_space; 815 obj_write.length = obj.length; 816 obj_write.parent = obj.parent; 817 obj_write.parent_offset = obj.parent_offset; 818 view.write::<BinderBufferObject>(offset, &obj_write)?; 819 } 820 BinderObjectRef::Fda(obj) => { 821 if !allow_fds { 822 return Err(EPERM.into()); 823 } 824 let parent_index = usize::try_from(obj.parent).map_err(|_| EINVAL)?; 825 let parent_offset = usize::try_from(obj.parent_offset).map_err(|_| EINVAL)?; 826 let num_fds = usize::try_from(obj.num_fds).map_err(|_| EINVAL)?; 827 let fds_len = num_fds.checked_mul(size_of::<u32>()).ok_or(EINVAL)?; 828 829 if !is_aligned(parent_offset, size_of::<u32>()) { 830 binder_debug!(UserError, "FDA parent offset not aligned correctly"); 831 return Err(EINVAL.into()); 832 } 833 834 let info = sg_state.validate_parent_fixup(parent_index, parent_offset, fds_len)?; 835 view.alloc.info_add_fd_reserve(num_fds)?; 836 837 sg_state.ancestors.truncate(info.num_ancestors); 838 let parent_entry = match sg_state.sg_entries.get_mut(info.parent_sg_index) { 839 Some(parent_entry) => parent_entry, 840 None => { 841 pr_err!( 842 "validate_parent_fixup returned index out of bounds for sg.entries" 843 ); 844 return Err(EINVAL.into()); 845 } 846 }; 847 848 if !is_aligned(parent_entry.sender_uaddr, size_of::<u32>()) { 849 binder_debug!(UserError, "FDA parent buffer not aligned correctly"); 850 return Err(EINVAL.into()); 851 } 852 853 parent_entry.fixup_min_offset = info.new_min_offset; 854 parent_entry 855 .pointer_fixups 856 .push( 857 PointerFixupEntry::Skip { 858 skip: fds_len, 859 target_offset: info.target_offset, 860 }, 861 GFP_KERNEL, 862 ) 863 .map_err(|_| ENOMEM)?; 864 865 let fda_uaddr = parent_entry 866 .sender_uaddr 867 .checked_add(parent_offset) 868 .ok_or(EINVAL)?; 869 870 let mut fda_bytes = KVec::new(); 871 UserSlice::new(UserPtr::from_addr(fda_uaddr as usize), fds_len) 872 .read_all(&mut fda_bytes, GFP_KERNEL)?; 873 874 if fds_len != fda_bytes.len() { 875 pr_err!("UserSlice::read_all returned wrong length in BINDER_TYPE_FDA"); 876 return Err(EINVAL.into()); 877 } 878 879 for i in (0..fds_len).step_by(size_of::<u32>()) { 880 let fd = { 881 let mut fd_bytes = [0u8; size_of::<u32>()]; 882 fd_bytes.copy_from_slice(&fda_bytes[i..i + size_of::<u32>()]); 883 u32::from_ne_bytes(fd_bytes) 884 }; 885 886 let file = LocalFile::fget(fd)?; 887 // SAFETY: The binder driver never calls `fdget_pos` and this code runs from an 888 // ioctl, so there are no active calls to `fdget_pos` on this thread. 889 let file = unsafe { LocalFile::assume_no_fdget_pos(file) }; 890 security::binder_transfer_file( 891 &self.process.cred, 892 &view.alloc.process.cred, 893 &file, 894 )?; 895 896 // The `validate_parent_fixup` call ensuers that this addition will not 897 // overflow. 898 view.alloc.info_add_fd(file, info.target_offset + i, true)?; 899 } 900 drop(fda_bytes); 901 902 let mut obj_write = BinderFdArrayObject::default(); 903 obj_write.hdr.type_ = BINDER_TYPE_FDA; 904 obj_write.num_fds = obj.num_fds; 905 obj_write.parent = obj.parent; 906 obj_write.parent_offset = obj.parent_offset; 907 view.write::<BinderFdArrayObject>(offset, &obj_write)?; 908 } 909 } 910 Ok(()) 911 } 912 913 fn apply_sg(&self, alloc: &mut Allocation, sg_state: &mut ScatterGatherState) -> BinderResult { 914 for sg_entry in &mut sg_state.sg_entries { 915 let mut end_of_previous_fixup = sg_entry.offset; 916 let offset_end = sg_entry.offset.checked_add(sg_entry.length).ok_or(EINVAL)?; 917 918 let mut reader = 919 UserSlice::new(UserPtr::from_addr(sg_entry.sender_uaddr), sg_entry.length).reader(); 920 for fixup in &mut sg_entry.pointer_fixups { 921 let (fixup_len, fixup_offset) = match fixup { 922 PointerFixupEntry::Fixup { target_offset, .. } => { 923 (size_of::<u64>(), *target_offset) 924 } 925 PointerFixupEntry::Skip { 926 skip, 927 target_offset, 928 } => (*skip, *target_offset), 929 }; 930 931 let target_offset_end = fixup_offset.checked_add(fixup_len).ok_or(EINVAL)?; 932 if fixup_offset < end_of_previous_fixup || offset_end < target_offset_end { 933 binder_debug!( 934 UserError, 935 "fixups oob {fixup_offset} {end_of_previous_fixup} {offset_end} {target_offset_end}" 936 ); 937 return Err(EINVAL.into()); 938 } 939 940 let copy_off = end_of_previous_fixup; 941 let copy_len = fixup_offset - end_of_previous_fixup; 942 if let Err(err) = alloc.copy_into(&mut reader, copy_off, copy_len) { 943 binder_debug!(UserError, "failed copying into alloc: {err:?}"); 944 return Err(err.into()); 945 } 946 if let PointerFixupEntry::Fixup { pointer_value, .. } = fixup { 947 let res = alloc.write::<u64>(fixup_offset, pointer_value); 948 if let Err(err) = res { 949 binder_debug!(UserError, "failed copying ptr into alloc: {err:?}"); 950 return Err(err.into()); 951 } 952 } 953 if let Err(err) = reader.skip(fixup_len) { 954 binder_debug!( 955 UserError, 956 "failed skipping {fixup_len} from reader: {err:?}" 957 ); 958 return Err(err.into()); 959 } 960 end_of_previous_fixup = target_offset_end; 961 } 962 let copy_off = end_of_previous_fixup; 963 let copy_len = offset_end - end_of_previous_fixup; 964 if let Err(err) = alloc.copy_into(&mut reader, copy_off, copy_len) { 965 binder_debug!(UserError, "failed copying remainder into alloc: {err:?}"); 966 return Err(err.into()); 967 } 968 } 969 Ok(()) 970 } 971 972 /// This method copies the payload of a transaction into the target process. 973 /// 974 /// The resulting payload will have several different components, which will be stored next to 975 /// each other in the allocation. Furthermore, various objects can be embedded in the payload, 976 /// and those objects have to be translated so that they make sense to the target transaction. 977 pub(crate) fn copy_transaction_data( 978 &self, 979 to_process: Arc<Process>, 980 info: &mut TransactionInfo, 981 debug_id: usize, 982 allow_fds: bool, 983 txn_security_ctx_offset: Option<&mut usize>, 984 ) -> BinderResult<NewAllocation> { 985 let mut secctx = if let Some(offset) = txn_security_ctx_offset { 986 let secid = self.process.cred.get_secid(); 987 let ctx = match security::SecurityCtx::from_secid(secid) { 988 Ok(ctx) => ctx, 989 Err(err) => { 990 pr_warn!("Failed to get security ctx for id {}: {:?}", secid, err); 991 return Err(err.into()); 992 } 993 }; 994 Some((offset, ctx)) 995 } else { 996 None 997 }; 998 999 let data_size = info.data_size; 1000 let aligned_data_size = ptr_align(data_size).ok_or(EINVAL)?; 1001 let offsets_size = info.offsets_size; 1002 let buffers_size = info.buffers_size; 1003 let aligned_secctx_size = match secctx.as_ref() { 1004 Some((_offset, ctx)) => ptr_align(ctx.len()).ok_or(EINVAL)?, 1005 None => 0, 1006 }; 1007 1008 if !is_aligned(offsets_size, size_of::<u64>()) { 1009 return Err(EINVAL.into()); 1010 } 1011 if !is_aligned(buffers_size, size_of::<u64>()) { 1012 return Err(EINVAL.into()); 1013 } 1014 1015 // This guarantees that at least `sizeof(usize)` bytes will be allocated. 1016 let len = usize::max( 1017 aligned_data_size 1018 .checked_add(offsets_size) 1019 .and_then(|sum| sum.checked_add(buffers_size)) 1020 .and_then(|sum| sum.checked_add(aligned_secctx_size)) 1021 .ok_or(ENOMEM)?, 1022 size_of::<u64>(), 1023 ); 1024 let secctx_off = aligned_data_size + offsets_size + buffers_size; 1025 let mut alloc = match to_process.buffer_alloc(debug_id, len, info) { 1026 Ok(alloc) => alloc, 1027 Err(err) => { 1028 pr_warn!( 1029 "Failed to allocate buffer. len:{}, is_oneway:{}", 1030 len, 1031 info.is_oneway(), 1032 ); 1033 return Err(err); 1034 } 1035 }; 1036 1037 let mut buffer_reader = UserSlice::new(info.data_ptr, data_size).reader(); 1038 let mut end_of_previous_object = 0; 1039 let mut sg_state = None; 1040 1041 // Copy offsets if there are any. 1042 if offsets_size > 0 { 1043 let mut offsets_reader = UserSlice::new(info.offsets_ptr, offsets_size).reader(); 1044 1045 let offsets_start = aligned_data_size; 1046 let offsets_end = aligned_data_size + offsets_size; 1047 1048 // This state is used for BINDER_TYPE_PTR objects. 1049 let sg_state = sg_state.insert(ScatterGatherState { 1050 unused_buffer_space: UnusedBufferSpace { 1051 offset: offsets_end, 1052 limit: offsets_end + buffers_size, 1053 }, 1054 sg_entries: KVec::new(), 1055 ancestors: KVec::new(), 1056 }); 1057 1058 // Traverse the objects specified. 1059 let mut view = AllocationView::new(&mut alloc, data_size); 1060 for (index, index_offset) in (offsets_start..offsets_end) 1061 .step_by(size_of::<u64>()) 1062 .enumerate() 1063 { 1064 let offset = offsets_reader.read::<u64>()?; 1065 view.alloc.write(index_offset, &offset)?; 1066 let offset: usize = offset.try_into().map_err(|_| EINVAL)?; 1067 1068 if offset < end_of_previous_object || !is_aligned(offset, size_of::<u32>()) { 1069 binder_debug!(UserError, "got transaction with invalid offset"); 1070 return Err(EINVAL.into()); 1071 } 1072 1073 // Copy data between two objects. 1074 if end_of_previous_object < offset { 1075 view.copy_into( 1076 &mut buffer_reader, 1077 end_of_previous_object, 1078 offset - end_of_previous_object, 1079 )?; 1080 } 1081 1082 let mut object = BinderObject::read_from(&mut buffer_reader)?; 1083 1084 match self.translate_object( 1085 index, 1086 offset, 1087 object.as_ref(), 1088 &mut view, 1089 allow_fds, 1090 sg_state, 1091 ) { 1092 Ok(()) => end_of_previous_object = offset + object.size(), 1093 Err(err) => { 1094 binder_debug!(UserError, "error while translating object: {err:?}"); 1095 return Err(err); 1096 } 1097 } 1098 1099 // Update the indexes containing objects to clean up. 1100 let offset_after_object = index_offset + size_of::<u64>(); 1101 view.alloc 1102 .set_info_offsets(offsets_start..offset_after_object); 1103 } 1104 } 1105 1106 // Copy remaining raw data. 1107 alloc.copy_into( 1108 &mut buffer_reader, 1109 end_of_previous_object, 1110 data_size - end_of_previous_object, 1111 )?; 1112 1113 if let Some(sg_state) = sg_state.as_mut() { 1114 self.apply_sg(&mut alloc, sg_state)?; 1115 } 1116 1117 if let Some((off_out, secctx)) = secctx.as_mut() { 1118 if let Err(err) = alloc.write(secctx_off, secctx.as_bytes()) { 1119 binder_debug!(UserError, "failed to write security context: {err:?}"); 1120 return Err(err.into()); 1121 } 1122 **off_out = secctx_off; 1123 } 1124 Ok(alloc) 1125 } 1126 1127 fn unwind_transaction_stack(self: &Arc<Self>) { 1128 let mut thread = self.clone(); 1129 while let Ok(transaction) = { 1130 let mut inner = thread.inner.lock(); 1131 inner.pop_transaction_to_reply(thread.as_ref()) 1132 } { 1133 binder_debug!( 1134 DeadTransaction, 1135 "release transaction {} in, still active", 1136 transaction.debug_id 1137 ); 1138 1139 let reply = Err(BR_DEAD_REPLY); 1140 if !transaction 1141 .from 1142 .deliver_single_reply(reply, &transaction, None) 1143 { 1144 break; 1145 } 1146 1147 thread = transaction.from.clone(); 1148 } 1149 } 1150 1151 pub(crate) fn deliver_reply( 1152 &self, 1153 reply: Result<DLArc<Transaction>, u32>, 1154 transaction: &DArc<Transaction>, 1155 extended_error: Option<ExtendedError>, 1156 ) { 1157 if self.deliver_single_reply(reply, transaction, extended_error) { 1158 transaction.from.unwind_transaction_stack(); 1159 } 1160 } 1161 1162 /// Delivers a reply to the thread that started a transaction. The reply can either be a 1163 /// reply-transaction or an error code to be delivered instead. 1164 /// 1165 /// Returns whether the thread is dead. If it is, the caller is expected to unwind the 1166 /// transaction stack by completing transactions for threads that are dead. 1167 fn deliver_single_reply( 1168 &self, 1169 reply: Result<DLArc<Transaction>, u32>, 1170 transaction: &DArc<Transaction>, 1171 extended_error: Option<ExtendedError>, 1172 ) -> bool { 1173 if let Ok(transaction) = &reply { 1174 crate::trace::trace_transaction(true, transaction, Some(&self.task)); 1175 transaction.set_outstanding(&mut self.process.inner.lock()); 1176 } 1177 1178 let ret = { 1179 let mut inner = self.inner.lock(); 1180 if !inner.pop_transaction_replied(transaction) { 1181 return false; 1182 } 1183 1184 if inner.is_dead { 1185 return true; 1186 } 1187 1188 if let Some(ee) = extended_error { 1189 if inner.extended_error.command == BR_OK { 1190 inner.extended_error = ee; 1191 } 1192 } 1193 1194 match reply { 1195 Ok(work) => inner.push_work(work), 1196 Err(code) => inner.push_reply_work(code), 1197 } 1198 }; 1199 1200 // Notify the thread now that we've released the inner lock. 1201 self.work_condvar.notify_sync(); 1202 if matches!(ret, PushWorkRes::OkNotifyPoll) { 1203 self.process.notify_poll(true); 1204 } 1205 false 1206 } 1207 1208 /// Determines if the given transaction is the current transaction for this thread. 1209 fn is_current_transaction(&self, transaction: &DArc<Transaction>) -> bool { 1210 let inner = self.inner.lock(); 1211 match &inner.current_transaction { 1212 None => false, 1213 Some(current) => Arc::ptr_eq(current, transaction), 1214 } 1215 } 1216 1217 /// Determines the current top of the transaction stack. It fails if the top is in another 1218 /// thread (i.e., this thread belongs to a stack but it has called another thread). The top is 1219 /// [`None`] if the thread is not currently participating in a transaction stack. 1220 fn top_of_transaction_stack(&self) -> Result<Option<DArc<Transaction>>> { 1221 let inner = self.inner.lock(); 1222 if let Some(cur) = &inner.current_transaction { 1223 if core::ptr::eq(self, cur.from.as_ref()) { 1224 pr_warn!("got new transaction with bad transaction stack"); 1225 return Err(EINVAL); 1226 } 1227 Ok(Some(cur.clone())) 1228 } else { 1229 Ok(None) 1230 } 1231 } 1232 1233 // No inlining avoids allocating stack space for `BinderTransactionData` for the entire 1234 // duration of `transaction()`. 1235 #[inline(never)] 1236 fn read_transaction_info( 1237 &self, 1238 cmd: u32, 1239 reader: &mut UserSliceReader, 1240 info: &mut TransactionInfo, 1241 ) -> Result<()> { 1242 let td = match cmd { 1243 BC_TRANSACTION | BC_REPLY => { 1244 reader.read::<BinderTransactionData>()?.with_buffers_size(0) 1245 } 1246 BC_TRANSACTION_SG | BC_REPLY_SG => reader.read::<BinderTransactionDataSg>()?, 1247 _ => return Err(EINVAL), 1248 }; 1249 1250 // SAFETY: Above `read` call initializes all bytes, so this union read is ok. 1251 let trd_data_ptr = unsafe { &td.transaction_data.data.ptr }; 1252 1253 info.is_reply = matches!(cmd, BC_REPLY | BC_REPLY_SG); 1254 info.from_pid = self.process.task.pid(); 1255 info.from_tid = self.id; 1256 info.code = td.transaction_data.code; 1257 info.flags = td.transaction_data.flags; 1258 info.data_ptr = UserPtr::from_addr(trd_data_ptr.buffer as usize); 1259 info.data_size = td.transaction_data.data_size as usize; 1260 info.offsets_ptr = UserPtr::from_addr(trd_data_ptr.offsets as usize); 1261 info.offsets_size = td.transaction_data.offsets_size as usize; 1262 info.buffers_size = td.buffers_size as usize; 1263 // SAFETY: Above `read` call initializes all bytes, so this union read is ok. 1264 info.target_handle = unsafe { td.transaction_data.target.handle }; 1265 1266 info.debug_id = super::next_debug_id(); 1267 1268 Ok(()) 1269 } 1270 1271 #[inline(never)] 1272 fn transaction(self: &Arc<Self>, cmd: u32, reader: &mut UserSliceReader) -> Result<()> { 1273 let mut info = TransactionInfo::zeroed(); 1274 self.read_transaction_info(cmd, reader, &mut info)?; 1275 1276 self.clear_extended_error(info.debug_id); 1277 1278 let ret = if info.is_reply { 1279 self.reply_inner(&mut info) 1280 } else if info.is_oneway() { 1281 self.oneway_transaction_inner(&mut info) 1282 } else { 1283 self.transaction_inner(&mut info) 1284 }; 1285 1286 if let Err(err) = ret { 1287 self.push_return_work(err.reply); 1288 if err.reply != BR_TRANSACTION_COMPLETE { 1289 info.reply = err.reply; 1290 if let Some(source) = &err.source { 1291 info.errno = source.to_errno(); 1292 1293 { 1294 let mut inner = self.inner.lock(); 1295 inner.extended_error = 1296 ExtendedError::new(info.debug_id as u32, err.reply, source.to_errno()); 1297 } 1298 } 1299 1300 binder_debug!( 1301 FailedTransaction, 1302 "transaction {} to {}:{} failed {:?}, code {} size {}-{}", 1303 if info.is_reply { 1304 "reply" 1305 } else if info.is_oneway() { 1306 "async" 1307 } else { 1308 "call" 1309 }, 1310 info.to_pid, 1311 info.to_tid, 1312 err, 1313 info.code, 1314 info.data_size, 1315 info.offsets_size 1316 ); 1317 } 1318 } 1319 1320 if info.oneway_spam_suspect { 1321 // If this is both a oneway spam suspect and a failure, we report it twice. This is 1322 // useful in case the transaction failed with BR_TRANSACTION_PENDING_FROZEN. 1323 info.report_netlink(BR_ONEWAY_SPAM_SUSPECT, &self.process.ctx); 1324 } 1325 if info.reply != 0 { 1326 info.report_netlink(info.reply, &self.process.ctx); 1327 } 1328 1329 Ok(()) 1330 } 1331 1332 fn transaction_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResult { 1333 let node_ref = self.process.get_transaction_node(info.target_handle)?; 1334 info.to_pid = node_ref.node.owner.task.pid(); 1335 security::binder_transaction(&self.process.cred, &node_ref.node.owner.cred)?; 1336 // TODO: We need to ensure that there isn't a pending transaction in the work queue. How 1337 // could this happen? 1338 let top = self.top_of_transaction_stack()?; 1339 let list_completion = DTRWrap::arc_try_new(DeliverCode::new( 1340 BR_TRANSACTION_COMPLETE, 1341 self.process.task.pid(), 1342 ))?; 1343 let completion = list_completion.clone_arc(); 1344 let transaction = Transaction::new(node_ref, top, self, info)?; 1345 1346 // Check that the transaction stack hasn't changed while the lock was released, then update 1347 // it with the new transaction. 1348 { 1349 let mut inner = self.inner.lock(); 1350 if !transaction.is_stacked_on(&inner.current_transaction) { 1351 binder_debug!(UserError, "got new transaction with bad transaction stack"); 1352 return Err(EINVAL.into()); 1353 } 1354 inner.current_transaction = Some(transaction.clone_arc()); 1355 // We push the completion as a deferred work so that we wait for the reply before 1356 // returning to userland. 1357 inner.push_work_deferred(list_completion); 1358 } 1359 1360 if let Err(e) = transaction.submit(info) { 1361 completion.skip(); 1362 // Define `transaction` first to drop it after `inner`. 1363 let transaction; 1364 let mut inner = self.inner.lock(); 1365 transaction = inner.current_transaction.take().unwrap(); 1366 inner.current_transaction = transaction.clone_next(); 1367 Err(e) 1368 } else { 1369 Ok(()) 1370 } 1371 } 1372 1373 fn reply_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResult { 1374 let orig = match self.inner.lock().pop_transaction_to_reply(self) { 1375 Ok(orig) => orig, 1376 Err(err) => { 1377 binder_debug!(UserError, "got reply transaction with no transaction stack"); 1378 return Err(err.into()); 1379 } 1380 }; 1381 if !orig.from.is_current_transaction(&orig) { 1382 binder_debug!( 1383 UserError, 1384 "got reply transaction with bad transaction stack" 1385 ); 1386 return Err(EINVAL.into()); 1387 } 1388 1389 info.to_tid = orig.from.id; 1390 info.to_pid = orig.from.process.task.pid(); 1391 1392 // We need to complete the transaction even if we cannot complete building the reply. 1393 let out = (|| -> BinderResult<_> { 1394 let completion = DTRWrap::arc_try_new(DeliverCode::new( 1395 BR_TRANSACTION_COMPLETE, 1396 self.process.task.pid(), 1397 ))?; 1398 let process = orig.from.process.clone(); 1399 let allow_fds = orig.flags & TF_ACCEPT_FDS != 0; 1400 let reply = Transaction::new_reply(self, process, info, allow_fds)?; 1401 // Not notifying: Reply to current thread. 1402 let _ = self.inner.lock().push_work(completion); 1403 orig.from.deliver_reply(Ok(reply), &orig, None); 1404 Ok(()) 1405 })() 1406 .map_err(|mut err| { 1407 // At this point we only return `BR_TRANSACTION_COMPLETE` to the caller, and we must let 1408 // the sender know that the transaction has completed (with an error in this case). 1409 1410 pr_warn!( 1411 "{}:{} reply to {} failed: {err:?}", 1412 info.from_pid, 1413 info.from_tid, 1414 info.to_pid 1415 ); 1416 let param = err.source.as_ref().map_or(0, |e| e.to_errno()); 1417 let ee = ExtendedError::new(info.debug_id as u32, err.reply, param); 1418 orig.from 1419 .deliver_reply(Err(BR_FAILED_REPLY), &orig, Some(ee)); 1420 info.reply = BR_FAILED_REPLY; 1421 err.reply = BR_TRANSACTION_COMPLETE; 1422 err 1423 }); 1424 1425 out 1426 } 1427 1428 fn oneway_transaction_inner(self: &Arc<Self>, info: &mut TransactionInfo) -> BinderResult { 1429 let node_ref = self.process.get_transaction_node(info.target_handle)?; 1430 info.to_pid = node_ref.node.owner.task.pid(); 1431 security::binder_transaction(&self.process.cred, &node_ref.node.owner.cred)?; 1432 let transaction = Transaction::new(node_ref, None, self, info)?; 1433 let code = if self.process.is_oneway_spam_detection_enabled() && info.oneway_spam_suspect { 1434 BR_ONEWAY_SPAM_SUSPECT 1435 } else { 1436 BR_TRANSACTION_COMPLETE 1437 }; 1438 let list_completion = 1439 DTRWrap::arc_try_new(DeliverCode::new(code, self.process.task.pid()))?; 1440 let completion = list_completion.clone_arc(); 1441 // Not notifying: Reply to current thread. 1442 let _ = self.inner.lock().push_work(list_completion); 1443 match transaction.submit(info) { 1444 Ok(()) => Ok(()), 1445 Err(err) => { 1446 completion.skip(); 1447 Err(err) 1448 } 1449 } 1450 } 1451 1452 fn write(self: &Arc<Self>, req: &mut BinderWriteRead) -> Result { 1453 let write_start = req.write_buffer.wrapping_add(req.write_consumed); 1454 let write_len = req.write_size.saturating_sub(req.write_consumed); 1455 let mut reader = 1456 UserSlice::new(UserPtr::from_addr(write_start as usize), write_len as usize).reader(); 1457 1458 while reader.len() >= size_of::<u32>() && self.inner.lock().return_work.is_unused() { 1459 let before = reader.len(); 1460 let cmd = reader.read::<u32>()?; 1461 crate::trace::trace_command(cmd); 1462 GLOBAL_STATS.inc_bc(cmd); 1463 self.process.stats.inc_bc(cmd); 1464 match cmd { 1465 BC_TRANSACTION | BC_TRANSACTION_SG | BC_REPLY | BC_REPLY_SG => { 1466 self.transaction(cmd, &mut reader)?; 1467 } 1468 BC_FREE_BUFFER => { 1469 let buffer = self.process.buffer_get(reader.read()?); 1470 if let Some(buffer) = buffer { 1471 if buffer.looper_need_return_on_free() { 1472 self.inner.lock().looper_need_return = true; 1473 } 1474 drop(buffer); 1475 } 1476 } 1477 BC_INCREFS => { 1478 self.process 1479 .as_arc_borrow() 1480 .update_ref(reader.read()?, true, false)? 1481 } 1482 BC_ACQUIRE => { 1483 self.process 1484 .as_arc_borrow() 1485 .update_ref(reader.read()?, true, true)? 1486 } 1487 BC_RELEASE => { 1488 self.process 1489 .as_arc_borrow() 1490 .update_ref(reader.read()?, false, true)? 1491 } 1492 BC_DECREFS => { 1493 self.process 1494 .as_arc_borrow() 1495 .update_ref(reader.read()?, false, false)? 1496 } 1497 BC_INCREFS_DONE => self.process.inc_ref_done(&mut reader, false)?, 1498 BC_ACQUIRE_DONE => self.process.inc_ref_done(&mut reader, true)?, 1499 BC_REQUEST_DEATH_NOTIFICATION => self.process.request_death(&mut reader, self)?, 1500 BC_CLEAR_DEATH_NOTIFICATION => self.process.clear_death(&mut reader, self)?, 1501 BC_DEAD_BINDER_DONE => self.process.dead_binder_done(reader.read()?, self), 1502 BC_REGISTER_LOOPER => { 1503 let valid = self.process.register_thread(); 1504 self.inner.lock().looper_register(valid); 1505 } 1506 BC_ENTER_LOOPER => self.inner.lock().looper_enter(), 1507 BC_EXIT_LOOPER => self.inner.lock().looper_exit(), 1508 BC_REQUEST_FREEZE_NOTIFICATION => self.process.request_freeze_notif(&mut reader)?, 1509 BC_CLEAR_FREEZE_NOTIFICATION => self.process.clear_freeze_notif(&mut reader)?, 1510 BC_FREEZE_NOTIFICATION_DONE => self.process.freeze_notif_done(&mut reader)?, 1511 1512 // Fail if given an unknown error code. 1513 // BC_ATTEMPT_ACQUIRE and BC_ACQUIRE_RESULT are no longer supported. 1514 _ => return Err(EINVAL), 1515 } 1516 // Update the number of write bytes consumed. 1517 req.write_consumed += (before - reader.len()) as u64; 1518 } 1519 1520 Ok(()) 1521 } 1522 1523 fn read(self: &Arc<Self>, req: &mut BinderWriteRead, wait: bool) -> Result { 1524 let read_start = req.read_buffer.wrapping_add(req.read_consumed); 1525 let read_len = req.read_size.saturating_sub(req.read_consumed); 1526 let mut writer = BinderReturnWriter::new( 1527 UserSlice::new(UserPtr::from_addr(read_start as usize), read_len as usize).writer(), 1528 self, 1529 ); 1530 let (in_pool, has_transaction, thread_todo, use_proc_queue) = { 1531 let inner = self.inner.lock(); 1532 ( 1533 inner.is_looper(), 1534 inner.current_transaction.is_some(), 1535 !inner.work_list.is_empty(), 1536 inner.should_use_process_work_queue(), 1537 ) 1538 }; 1539 1540 crate::trace::trace_wait_for_work(use_proc_queue, has_transaction, thread_todo); 1541 1542 let getter = if use_proc_queue { 1543 Self::get_work 1544 } else { 1545 Self::get_work_local 1546 }; 1547 1548 // Reserve some room at the beginning of the read buffer so that we can send a 1549 // BR_SPAWN_LOOPER if we need to. 1550 let mut has_noop_placeholder = false; 1551 if req.read_consumed == 0 { 1552 if let Err(err) = writer.write_code(BR_NOOP) { 1553 pr_warn!("Failure when writing BR_NOOP at beginning of buffer."); 1554 return Err(err); 1555 } 1556 has_noop_placeholder = true; 1557 } 1558 1559 // Loop doing work while there is room in the buffer. 1560 let initial_len = writer.len(); 1561 while writer.len() >= size_of::<uapi::binder_transaction_data_secctx>() + 4 { 1562 match getter(self, wait && initial_len == writer.len()) { 1563 Ok(Some(work)) => match work.into_arc().do_work(self, &mut writer) { 1564 Ok(true) => {} 1565 Ok(false) => break, 1566 Err(err) => { 1567 return Err(err); 1568 } 1569 }, 1570 Ok(None) => { 1571 break; 1572 } 1573 Err(err) => { 1574 // Propagate the error if we haven't written anything else. 1575 if err != EINTR && err != EAGAIN { 1576 pr_warn!("Failure in work getter: {:?}", err); 1577 } 1578 if initial_len == writer.len() { 1579 return Err(err); 1580 } else { 1581 break; 1582 } 1583 } 1584 } 1585 } 1586 1587 req.read_consumed += read_len - writer.len() as u64; 1588 1589 // Write BR_SPAWN_LOOPER if the process needs more threads for its pool. 1590 if has_noop_placeholder && in_pool && self.process.needs_thread() { 1591 let mut writer = UserSlice::new( 1592 UserPtr::from_addr(req.read_buffer as usize), 1593 req.read_size as usize, 1594 ) 1595 .writer(); 1596 writer.write(&BR_SPAWN_LOOPER)?; 1597 } 1598 Ok(()) 1599 } 1600 1601 pub(crate) fn write_read(self: &Arc<Self>, data: UserSlice, wait: bool) -> Result { 1602 let (mut reader, mut writer) = data.reader_writer(); 1603 let mut req = reader.read::<BinderWriteRead>()?; 1604 1605 // Go through the write buffer. 1606 let mut ret = Ok(()); 1607 if req.write_size > 0 { 1608 ret = self.write(&mut req); 1609 crate::trace::trace_write_done(ret); 1610 if let Err(err) = ret { 1611 pr_warn!( 1612 "Write failure {:?} in pid:{}", 1613 err, 1614 self.process.pid_in_current_ns() 1615 ); 1616 req.read_consumed = 0; 1617 writer.write(&req)?; 1618 self.inner.lock().looper_need_return = false; 1619 return ret; 1620 } 1621 } 1622 1623 // Go through the work queue. 1624 if req.read_size > 0 { 1625 ret = self.read(&mut req, wait); 1626 crate::trace::trace_read_done(ret); 1627 if ret.is_err() && ret != Err(EINTR) { 1628 pr_warn!( 1629 "Read failure {:?} in pid:{}", 1630 ret, 1631 self.process.pid_in_current_ns() 1632 ); 1633 } 1634 } 1635 1636 // Write the request back so that the consumed fields are visible to the caller. 1637 writer.write(&req)?; 1638 1639 self.inner.lock().looper_need_return = false; 1640 1641 ret 1642 } 1643 1644 pub(crate) fn poll(&self) -> Result<(bool, u32)> { 1645 let mut inner = self.inner.lock(); 1646 Ok((inner.should_use_process_work_queue(), inner.poll())) 1647 } 1648 1649 /// Make the call to `get_work` or `get_work_local` return immediately, if any. 1650 pub(crate) fn exit_looper(&self) { 1651 let mut inner = self.inner.lock(); 1652 let should_notify = inner.looper_flags & LOOPER_WAITING != 0; 1653 if should_notify { 1654 inner.looper_need_return = true; 1655 } 1656 drop(inner); 1657 1658 if should_notify { 1659 self.work_condvar.notify_one(); 1660 } 1661 } 1662 1663 pub(crate) fn release(self: &Arc<Self>) { 1664 self.inner.lock().is_dead = true; 1665 1666 self.unwind_transaction_stack(); 1667 1668 // Cancel all pending work items. 1669 while let Ok(Some(work)) = self.get_work_local(false) { 1670 work.into_arc().cancel(); 1671 } 1672 } 1673 } 1674 1675 #[pin_data] 1676 struct ThreadError { 1677 error_code: Atomic<u32>, 1678 pid: i32, 1679 #[pin] 1680 links_track: AtomicTracker, 1681 } 1682 1683 impl ThreadError { 1684 fn try_new(pid: i32) -> Result<DArc<Self>> { 1685 DTRWrap::arc_pin_init(pin_init!(Self { 1686 error_code: Atomic::new(BR_OK), 1687 pid, 1688 links_track <- AtomicTracker::new(), 1689 })) 1690 .map(ListArc::into_arc) 1691 } 1692 1693 fn set_error_code(&self, code: u32) { 1694 self.error_code.store(code, Relaxed); 1695 } 1696 1697 fn is_unused(&self) -> bool { 1698 self.error_code.load(Relaxed) == BR_OK 1699 } 1700 } 1701 1702 impl DeliverToRead for ThreadError { 1703 fn do_work( 1704 self: DArc<Self>, 1705 _thread: &Thread, 1706 writer: &mut BinderReturnWriter<'_>, 1707 ) -> Result<bool> { 1708 let code = self.error_code.load(Relaxed); 1709 self.error_code.store(BR_OK, Relaxed); 1710 writer.write_code(code)?; 1711 Ok(true) 1712 } 1713 1714 fn cancel(self: DArc<Self>) { 1715 let code = self.error_code.load(Relaxed); 1716 if code != BR_OK { 1717 binder_debug!( 1718 pid = self.pid, 1719 DeadTransaction, 1720 "undelivered TRANSACTION_ERROR: {code}" 1721 ); 1722 } 1723 } 1724 1725 fn should_sync_wakeup(&self) -> bool { 1726 false 1727 } 1728 1729 fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> { 1730 seq_print!( 1731 m, 1732 "{}transaction error: {}\n", 1733 prefix, 1734 self.error_code.load(Relaxed) 1735 ); 1736 Ok(()) 1737 } 1738 } 1739 1740 kernel::list::impl_list_arc_safe! { 1741 impl ListArcSafe<0> for ThreadError { 1742 tracked_by links_track: AtomicTracker; 1743 } 1744 } 1745