File Index
Files and directories
Sign in
FILE

thread.rs

File preview with syntax highlighting.

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