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