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