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