1 // SPDX-License-Identifier: GPL-2.0 2 3 // Copyright (C) 2025 Google LLC. 4 5 use kernel::{ 6 list::{AtomicTracker, List, ListArc, ListLinks, TryNewListArc}, 7 prelude::*, 8 seq_file::SeqFile, 9 seq_print, 10 sync::lock::{spinlock::SpinLockBackend, Guard}, 11 sync::{Arc, LockedBy, SpinLock}, 12 uapi, 13 }; 14 15 use crate::{ 16 defs::*, 17 error::BinderError, 18 process::{NodeRefInfo, Process, ProcessInner}, 19 thread::Thread, 20 transaction::Transaction, 21 BinderReturnWriter, DArc, DLArc, DTRWrap, DeliverToRead, 22 }; 23 24 use core::mem; 25 use core::ptr; 26 27 mod wrapper; 28 pub(crate) use self::wrapper::CritIncrWrapper; 29 30 #[derive(Debug)] 31 pub(crate) struct CouldNotDeliverCriticalIncrement; 32 33 /// Keeps track of how this node is scheduled. 34 /// 35 /// There are two ways to schedule a node to a work list. Just schedule the node itself, or 36 /// allocate a wrapper that references the node and schedule the wrapper. These wrappers exists to 37 /// make it possible to "move" a node from one list to another - when `do_work` is called directly 38 /// on the `Node`, then it's a no-op if there's also a pending wrapper. 39 /// 40 /// Wrappers are generally only needed for zero-to-one refcount increments, and there are two cases 41 /// of this: weak increments and strong increments. We call such increments "critical" because it 42 /// is critical that they are delivered to the thread doing the increment. Some examples: 43 /// 44 /// * One thread makes a zero-to-one strong increment, and another thread makes a zero-to-one weak 45 /// increment. Delivering the node to the thread doing the weak increment is wrong, since the 46 /// thread doing the strong increment may have ended a long time ago when the command is actually 47 /// processed by userspace. 48 /// 49 /// * We have a weak reference and are about to drop it on one thread. But then another thread does 50 /// a zero-to-one strong increment. If the strong increment gets sent to the thread that was 51 /// about to drop the weak reference, then the strong increment could be processed after the 52 /// other thread has already exited, which would be too late. 53 /// 54 /// Note that trying to create a `ListArc` to the node can succeed even if `has_pushed_node` is 55 /// set. This is because another thread might just have popped the node from a todo list, but not 56 /// yet called `do_work`. However, if `has_pushed_node` is false, then creating a `ListArc` should 57 /// always succeed. 58 /// 59 /// Like the other fields in `NodeInner`, the delivery state is protected by the process lock. 60 struct DeliveryState { 61 /// Is the `Node` currently scheduled? 62 has_pushed_node: bool, 63 64 /// Is a wrapper currently scheduled? 65 /// 66 /// The wrapper is used only for strong zero2one increments. 67 has_pushed_wrapper: bool, 68 69 /// Is the currently scheduled `Node` scheduled due to a weak zero2one increment? 70 /// 71 /// Weak zero2one operations are always scheduled using the `Node`. 72 has_weak_zero2one: bool, 73 74 /// Is the currently scheduled wrapper/`Node` scheduled due to a strong zero2one increment? 75 /// 76 /// If `has_pushed_wrapper` is set, then the strong zero2one increment was scheduled using the 77 /// wrapper. Otherwise, `has_pushed_node` must be set and it was scheduled using the `Node`. 78 has_strong_zero2one: bool, 79 } 80 81 impl DeliveryState { 82 fn should_normal_push(&self) -> bool { 83 !self.has_pushed_node && !self.has_pushed_wrapper 84 } 85 86 fn did_normal_push(&mut self) { 87 assert!(self.should_normal_push()); 88 self.has_pushed_node = true; 89 } 90 91 fn should_push_weak_zero2one(&self) -> bool { 92 !self.has_weak_zero2one && !self.has_strong_zero2one 93 } 94 95 fn can_push_weak_zero2one_normally(&self) -> bool { 96 !self.has_pushed_node 97 } 98 99 fn did_push_weak_zero2one(&mut self) { 100 assert!(self.should_push_weak_zero2one()); 101 assert!(self.can_push_weak_zero2one_normally()); 102 self.has_pushed_node = true; 103 self.has_weak_zero2one = true; 104 } 105 106 fn should_push_strong_zero2one(&self) -> bool { 107 !self.has_strong_zero2one 108 } 109 110 fn can_push_strong_zero2one_normally(&self) -> bool { 111 !self.has_pushed_node 112 } 113 114 fn did_push_strong_zero2one(&mut self) { 115 assert!(self.should_push_strong_zero2one()); 116 assert!(self.can_push_strong_zero2one_normally()); 117 self.has_pushed_node = true; 118 self.has_strong_zero2one = true; 119 } 120 121 fn did_push_strong_zero2one_wrapper(&mut self) { 122 assert!(self.should_push_strong_zero2one()); 123 assert!(!self.can_push_strong_zero2one_normally()); 124 self.has_pushed_wrapper = true; 125 self.has_strong_zero2one = true; 126 } 127 } 128 129 struct CountState { 130 /// The reference count. 131 count: usize, 132 /// Whether the process that owns this node thinks that we hold a refcount on it. (Note that 133 /// even if count is greater than one, we only increment it once in the owning process.) 134 has_count: bool, 135 } 136 137 impl CountState { 138 fn new() -> Self { 139 Self { 140 count: 0, 141 has_count: false, 142 } 143 } 144 } 145 146 struct NodeInner { 147 /// Strong refcounts held on this node by `NodeRef` objects. 148 strong: CountState, 149 /// Weak refcounts held on this node by `NodeRef` objects. 150 weak: CountState, 151 delivery_state: DeliveryState, 152 /// The binder driver guarantees that oneway transactions sent to the same node are serialized, 153 /// that is, userspace will not be given the next one until it has finished processing the 154 /// previous oneway transaction. This is done to avoid the case where two oneway transactions 155 /// arrive in opposite order from the order in which they were sent. (E.g., they could be 156 /// delivered to two different threads, which could appear as-if they were sent in opposite 157 /// order.) 158 /// 159 /// To fix that, we store pending oneway transactions in a separate list in the node, and don't 160 /// deliver the next oneway transaction until userspace signals that it has finished processing 161 /// the previous oneway transaction by calling the `BC_FREE_BUFFER` ioctl. 162 oneway_todo: List<DTRWrap<Transaction>>, 163 /// Keeps track of whether this node has a pending oneway transaction. 164 /// 165 /// When this is true, incoming oneway transactions are stored in `oneway_todo`, instead of 166 /// being delivered directly to the process. 167 has_oneway_transaction: bool, 168 /// List of processes to deliver a notification to when this node is destroyed (usually due to 169 /// the process dying). 170 death_list: List<DTRWrap<NodeDeath>, 1>, 171 /// List of processes to deliver freeze notifications to. 172 freeze_list: KVVec<Arc<Process>>, 173 /// The number of active BR_INCREFS or BR_ACQUIRE operations. (should be maximum two) 174 /// 175 /// If this is non-zero, then we postpone any BR_RELEASE or BR_DECREFS notifications until the 176 /// active operations have ended. This avoids the situation an increment and decrement get 177 /// reordered from userspace's perspective. 178 active_inc_refs: u8, 179 /// List of `NodeRefInfo` objects that reference this node. 180 refs: List<NodeRefInfo, { NodeRefInfo::LIST_NODE }>, 181 } 182 183 use kernel::bindings::rb_node_layout; 184 use mem::offset_of; 185 pub(crate) const NODE_LAYOUT: rb_node_layout = rb_node_layout { 186 arc_offset: Arc::<Node>::DATA_OFFSET + offset_of!(DTRWrap<Node>, wrapped), 187 debug_id: offset_of!(Node, debug_id), 188 ptr: offset_of!(Node, ptr), 189 }; 190 191 #[pin_data] 192 pub(crate) struct Node { 193 pub(crate) debug_id: usize, 194 ptr: u64, 195 pub(crate) cookie: u64, 196 pub(crate) flags: u32, 197 pub(crate) owner: Arc<Process>, 198 inner: LockedBy<NodeInner, ProcessInner>, 199 #[pin] 200 links_track: AtomicTracker, 201 } 202 203 kernel::list::impl_list_arc_safe! { 204 impl ListArcSafe<0> for Node { 205 tracked_by links_track: AtomicTracker; 206 } 207 } 208 209 // Make `oneway_todo` work. 210 kernel::list::impl_list_item! { 211 impl ListItem<0> for DTRWrap<Transaction> { 212 using ListLinks { self.links.inner }; 213 } 214 } 215 216 impl Node { 217 pub(crate) fn new( 218 ptr: u64, 219 cookie: u64, 220 flags: u32, 221 owner: Arc<Process>, 222 ) -> impl PinInit<Self> { 223 pin_init!(Self { 224 inner: LockedBy::new( 225 &owner.inner, 226 NodeInner { 227 strong: CountState::new(), 228 weak: CountState::new(), 229 delivery_state: DeliveryState { 230 has_pushed_node: false, 231 has_pushed_wrapper: false, 232 has_weak_zero2one: false, 233 has_strong_zero2one: false, 234 }, 235 death_list: List::new(), 236 oneway_todo: List::new(), 237 freeze_list: KVVec::new(), 238 has_oneway_transaction: false, 239 active_inc_refs: 0, 240 refs: List::new(), 241 }, 242 ), 243 debug_id: super::next_debug_id(), 244 ptr, 245 cookie, 246 flags, 247 owner, 248 links_track <- AtomicTracker::new(), 249 }) 250 } 251 252 pub(crate) fn has_oneway_transaction(&self, owner_inner: &mut ProcessInner) -> bool { 253 let inner = self.inner.access_mut(owner_inner); 254 inner.has_oneway_transaction 255 } 256 257 #[inline(never)] 258 pub(crate) fn full_debug_print( 259 &self, 260 m: &SeqFile, 261 owner_inner: &mut ProcessInner, 262 ) -> Result<()> { 263 let inner = self.inner.access_mut(owner_inner); 264 seq_print!( 265 m, 266 " node {}: u{:016x} c{:016x} hs {} hw {} cs {} cw {}", 267 self.debug_id, 268 self.ptr, 269 self.cookie, 270 inner.strong.has_count, 271 inner.weak.has_count, 272 inner.strong.count, 273 inner.weak.count, 274 ); 275 if !inner.refs.is_empty() { 276 seq_print!(m, " proc"); 277 for node_ref in &inner.refs { 278 seq_print!(m, " {}", node_ref.process.task.pid()); 279 } 280 } 281 seq_print!(m, "\n"); 282 for t in &inner.oneway_todo { 283 t.debug_print_inner(m, " pending async transaction "); 284 } 285 Ok(()) 286 } 287 288 /// Insert the `NodeRef` into this `refs` list. 289 /// 290 /// # Safety 291 /// 292 /// It must be the case that `info.node_ref.node` is this node. 293 pub(crate) unsafe fn insert_node_info( 294 &self, 295 info: ListArc<NodeRefInfo, { NodeRefInfo::LIST_NODE }>, 296 ) { 297 self.inner 298 .access_mut(&mut self.owner.inner.lock()) 299 .refs 300 .push_front(info); 301 } 302 303 /// Insert the `NodeRef` into this `refs` list. 304 /// 305 /// # Safety 306 /// 307 /// It must be the case that `info.node_ref.node` is this node. 308 pub(crate) unsafe fn remove_node_info( 309 &self, 310 info: &NodeRefInfo, 311 ) -> Option<ListArc<NodeRefInfo, { NodeRefInfo::LIST_NODE }>> { 312 // SAFETY: We always insert `NodeRefInfo` objects into the `refs` list of the node that it 313 // references in `info.node_ref.node`. That is this node, so `info` cannot possibly be in 314 // the `refs` list of another node. 315 unsafe { 316 self.inner 317 .access_mut(&mut self.owner.inner.lock()) 318 .refs 319 .remove(info) 320 } 321 } 322 323 /// An id that is unique across all binder nodes on the system. Used as the key in the 324 /// `by_node` map. 325 pub(crate) fn global_id(&self) -> usize { 326 ptr::from_ref(self).addr() 327 } 328 329 pub(crate) fn get_id(&self) -> (u64, u64) { 330 (self.ptr, self.cookie) 331 } 332 333 pub(crate) fn add_death( 334 &self, 335 death: ListArc<DTRWrap<NodeDeath>, 1>, 336 guard: &mut Guard<'_, ProcessInner, SpinLockBackend>, 337 ) { 338 assert!( 339 core::ptr::eq(self, &**death.node), 340 "attempt to add NodeDeath to the wrong death list" 341 ); 342 self.inner.access_mut(guard).death_list.push_back(death); 343 } 344 345 pub(crate) fn inc_ref_done_locked( 346 self: &DArc<Node>, 347 _strong: bool, 348 owner_inner: &mut ProcessInner, 349 ) -> Option<DLArc<Node>> { 350 let inner = self.inner.access_mut(owner_inner); 351 if inner.active_inc_refs == 0 { 352 binder_debug!(UserError, "inc_ref_done called when no active inc_refs"); 353 return None; 354 } 355 356 inner.active_inc_refs -= 1; 357 if inner.active_inc_refs == 0 { 358 // Having active inc_refs can inhibit dropping of ref-counts. Calculate whether we 359 // would send a refcount decrement, and if so, tell the caller to schedule us. 360 let strong = inner.strong.count > 0; 361 let has_strong = inner.strong.has_count; 362 let weak = strong || inner.weak.count > 0; 363 let has_weak = inner.weak.has_count; 364 365 let should_drop_weak = !weak && has_weak; 366 let should_drop_strong = !strong && has_strong; 367 368 // If we want to drop the ref-count again, tell the caller to schedule a work node for 369 // that. 370 let need_push = should_drop_weak || should_drop_strong; 371 372 if need_push && inner.delivery_state.should_normal_push() { 373 let list_arc = ListArc::try_from_arc(self.clone()).ok().unwrap(); 374 inner.delivery_state.did_normal_push(); 375 Some(list_arc) 376 } else { 377 None 378 } 379 } else { 380 None 381 } 382 } 383 384 pub(crate) fn update_refcount_locked( 385 self: &DArc<Node>, 386 inc: bool, 387 strong: bool, 388 count: usize, 389 owner_inner: &mut ProcessInner, 390 ) -> Option<DLArc<Node>> { 391 let is_dead = owner_inner.is_dead; 392 let inner = self.inner.access_mut(owner_inner); 393 394 // Get a reference to the state we'll update. 395 let state = if strong { 396 &mut inner.strong 397 } else { 398 &mut inner.weak 399 }; 400 401 // Update the count and determine whether we need to push work. 402 let need_push = if inc { 403 state.count += count; 404 // TODO: This method shouldn't be used for zero-to-one increments. 405 !is_dead && !state.has_count 406 } else { 407 if state.count < count { 408 pr_err!("Failure: refcount underflow!"); 409 return None; 410 } 411 state.count -= count; 412 !is_dead && state.count == 0 && state.has_count 413 }; 414 415 if need_push && inner.delivery_state.should_normal_push() { 416 let list_arc = ListArc::try_from_arc(self.clone()).ok().unwrap(); 417 inner.delivery_state.did_normal_push(); 418 Some(list_arc) 419 } else { 420 None 421 } 422 } 423 424 pub(crate) fn incr_refcount_allow_zero2one( 425 self: &DArc<Self>, 426 strong: bool, 427 owner_inner: &mut ProcessInner, 428 ) -> Result<Option<DLArc<Node>>, CouldNotDeliverCriticalIncrement> { 429 let is_dead = owner_inner.is_dead; 430 let inner = self.inner.access_mut(owner_inner); 431 432 // Get a reference to the state we'll update. 433 let state = if strong { 434 &mut inner.strong 435 } else { 436 &mut inner.weak 437 }; 438 439 // Update the count and determine whether we need to push work. 440 state.count += 1; 441 if is_dead || state.has_count { 442 return Ok(None); 443 } 444 445 // Userspace needs to be notified of this. 446 if !strong && inner.delivery_state.should_push_weak_zero2one() { 447 assert!(inner.delivery_state.can_push_weak_zero2one_normally()); 448 let list_arc = ListArc::try_from_arc(self.clone()).ok().unwrap(); 449 inner.delivery_state.did_push_weak_zero2one(); 450 Ok(Some(list_arc)) 451 } else if strong && inner.delivery_state.should_push_strong_zero2one() { 452 if inner.delivery_state.can_push_strong_zero2one_normally() { 453 let list_arc = ListArc::try_from_arc(self.clone()).ok().unwrap(); 454 inner.delivery_state.did_push_strong_zero2one(); 455 Ok(Some(list_arc)) 456 } else { 457 state.count -= 1; 458 Err(CouldNotDeliverCriticalIncrement) 459 } 460 } else { 461 // Work is already pushed, and we don't need to push again. 462 Ok(None) 463 } 464 } 465 466 pub(crate) fn incr_refcount_allow_zero2one_with_wrapper( 467 self: &DArc<Self>, 468 strong: bool, 469 wrapper: CritIncrWrapper, 470 owner_inner: &mut ProcessInner, 471 ) -> Option<DLArc<dyn DeliverToRead>> { 472 match self.incr_refcount_allow_zero2one(strong, owner_inner) { 473 Ok(Some(node)) => Some(node as DLArc<dyn DeliverToRead>), 474 Ok(None) => None, 475 Err(CouldNotDeliverCriticalIncrement) => { 476 assert!(strong); 477 let inner = self.inner.access_mut(owner_inner); 478 inner.strong.count += 1; 479 inner.delivery_state.did_push_strong_zero2one_wrapper(); 480 Some(wrapper.init(self.clone())) 481 } 482 } 483 } 484 485 pub(crate) fn update_refcount(self: &DArc<Self>, inc: bool, count: usize, strong: bool) { 486 self.owner 487 .inner 488 .lock() 489 .update_node_refcount(self, inc, strong, count, None); 490 } 491 492 pub(crate) fn populate_counts( 493 &self, 494 out: &mut BinderNodeInfoForRef, 495 guard: &Guard<'_, ProcessInner, SpinLockBackend>, 496 ) { 497 let inner = self.inner.access(guard); 498 out.strong_count = inner.strong.count as u32; 499 out.weak_count = inner.weak.count as u32; 500 } 501 502 pub(crate) fn populate_debug_info( 503 &self, 504 out: &mut BinderNodeDebugInfo, 505 guard: &Guard<'_, ProcessInner, SpinLockBackend>, 506 ) { 507 out.ptr = self.ptr as uapi::binder_uintptr_t; 508 out.cookie = self.cookie as uapi::binder_uintptr_t; 509 let inner = self.inner.access(guard); 510 if inner.strong.has_count { 511 out.has_strong_ref = 1; 512 } 513 if inner.weak.has_count { 514 out.has_weak_ref = 1; 515 } 516 } 517 518 pub(crate) fn force_has_count(&self, guard: &mut Guard<'_, ProcessInner, SpinLockBackend>) { 519 let inner = self.inner.access_mut(guard); 520 inner.strong.has_count = true; 521 inner.weak.has_count = true; 522 } 523 524 fn write(&self, writer: &mut BinderReturnWriter<'_>, code: u32) -> Result { 525 writer.write_code(code)?; 526 writer.write_payload(&self.ptr)?; 527 writer.write_payload(&self.cookie)?; 528 Ok(()) 529 } 530 531 pub(crate) fn submit_oneway( 532 &self, 533 transaction: DLArc<Transaction>, 534 guard: &mut Guard<'_, ProcessInner, SpinLockBackend>, 535 ) -> Result<(), (BinderError, DLArc<dyn DeliverToRead>)> { 536 if guard.is_dead { 537 return Err((BinderError::new_dead(), transaction)); 538 } 539 540 let inner = self.inner.access_mut(guard); 541 if inner.has_oneway_transaction { 542 inner.oneway_todo.push_back(transaction); 543 } else { 544 inner.has_oneway_transaction = true; 545 guard.push_work(&self.owner, transaction)?; 546 } 547 Ok(()) 548 } 549 550 pub(crate) fn release(&self) { 551 let mut guard = self.owner.inner.lock(); 552 while let Some(work) = self.inner.access_mut(&mut guard).oneway_todo.pop_front() { 553 drop(guard); 554 work.into_arc().cancel(); 555 guard = self.owner.inner.lock(); 556 } 557 558 while let Some(death) = self.inner.access_mut(&mut guard).death_list.pop_front() { 559 drop(guard); 560 death.into_arc().set_dead(); 561 guard = self.owner.inner.lock(); 562 } 563 } 564 565 pub(crate) fn pending_oneway_finished(&self) { 566 let mut guard = self.owner.inner.lock(); 567 if guard.is_dead { 568 // Cleanup will happen in `Process::deferred_release`. 569 return; 570 } 571 572 let inner = self.inner.access_mut(&mut guard); 573 574 let transaction = inner.oneway_todo.pop_front(); 575 inner.has_oneway_transaction = transaction.is_some(); 576 if let Some(transaction) = transaction { 577 match guard.push_work(&self.owner, transaction) { 578 Ok(()) => {} 579 Err((_err, work)) => { 580 // Process is dead. 581 // This shouldn't happen due to the `is_dead` check, but if it does, just drop 582 // the transaction and return. 583 drop(guard); 584 drop(work); 585 } 586 } 587 } 588 } 589 590 /// Finds an outdated transaction that the given transaction can replace. 591 /// 592 /// If one is found, it is removed from the list and returned. 593 pub(crate) fn take_outdated_transaction( 594 &self, 595 new: &Transaction, 596 guard: &mut Guard<'_, ProcessInner, SpinLockBackend>, 597 ) -> Option<DLArc<Transaction>> { 598 let inner = self.inner.access_mut(guard); 599 let mut cursor = inner.oneway_todo.cursor_front(); 600 while let Some(next) = cursor.peek_next() { 601 if new.can_replace(&next) { 602 return Some(next.remove()); 603 } 604 cursor.move_next(); 605 } 606 None 607 } 608 609 /// This is split into a separate function since it's called by both `Node::do_work` and 610 /// `NodeWrapper::do_work`. 611 fn do_work_locked( 612 &self, 613 writer: &mut BinderReturnWriter<'_>, 614 mut guard: Guard<'_, ProcessInner, SpinLockBackend>, 615 ) -> Result<bool> { 616 let inner = self.inner.access_mut(&mut guard); 617 let strong = inner.strong.count > 0; 618 let has_strong = inner.strong.has_count; 619 let weak = strong || inner.weak.count > 0; 620 let has_weak = inner.weak.has_count; 621 622 if weak && !has_weak { 623 inner.weak.has_count = true; 624 inner.active_inc_refs += 1; 625 } 626 627 if strong && !has_strong { 628 inner.strong.has_count = true; 629 inner.active_inc_refs += 1; 630 } 631 632 let no_active_inc_refs = inner.active_inc_refs == 0; 633 let should_drop_weak = no_active_inc_refs && (!weak && has_weak); 634 let should_drop_strong = no_active_inc_refs && (!strong && has_strong); 635 if should_drop_weak { 636 inner.weak.has_count = false; 637 } 638 if should_drop_strong { 639 inner.strong.has_count = false; 640 } 641 if no_active_inc_refs && !weak { 642 // Remove the node if there are no references to it. 643 guard.remove_node(self.ptr); 644 } 645 drop(guard); 646 647 if weak && !has_weak { 648 self.write(writer, BR_INCREFS)?; 649 } 650 if strong && !has_strong { 651 self.write(writer, BR_ACQUIRE)?; 652 } 653 if should_drop_strong { 654 self.write(writer, BR_RELEASE)?; 655 } 656 if should_drop_weak { 657 self.write(writer, BR_DECREFS)?; 658 } 659 660 Ok(true) 661 } 662 663 pub(crate) fn add_freeze_listener( 664 &self, 665 process: &Arc<Process>, 666 // If the vector needs to be resized, it's done via this argument. 667 vec_alloc: &mut KVVec<Arc<Process>>, 668 ) -> Result<Result<(), usize>> { 669 let mut guard = self.owner.inner.lock(); 670 // Do not check for `guard.dead`. The `dead` flag that matters here is the owner of the 671 // listener, not the target. 672 let inner = self.inner.access_mut(&mut guard); 673 let len = inner.freeze_list.len(); 674 if len == inner.freeze_list.capacity() { 675 if len >= vec_alloc.capacity() { 676 // Request the caller to reallocate. 677 return Ok(Err((1 + len).next_power_of_two())); 678 } 679 mem::swap(&mut inner.freeze_list, vec_alloc); 680 for elem in vec_alloc.drain_all() { 681 inner.freeze_list.push_within_capacity(elem)?; 682 } 683 } 684 inner.freeze_list.push_within_capacity(process.clone())?; 685 Ok(Ok(())) 686 } 687 688 pub(crate) fn remove_freeze_listener(&self, p: &Process) -> KVVec<Arc<Process>> { 689 let mut guard = self.owner.inner.lock(); 690 let inner = self.inner.access_mut(&mut guard); 691 let len = inner.freeze_list.len(); 692 inner 693 .freeze_list 694 .retain(|proc| !core::ptr::eq::<Process>(&**proc, p)); 695 if len == inner.freeze_list.len() { 696 pr_warn!( 697 "Could not remove freeze listener for {}\n", 698 p.pid_in_current_ns() 699 ); 700 } 701 // If the vector is empty it needs to be freed. However, we can't free it here because that 702 // might sleep, so return it to the caller. 703 if inner.freeze_list.is_empty() { 704 return mem::take(&mut inner.freeze_list); 705 } 706 KVVec::new() 707 } 708 709 pub(crate) fn freeze_list<'a>(&'a self, guard: &'a ProcessInner) -> &'a [Arc<Process>] { 710 &self.inner.access(guard).freeze_list 711 } 712 } 713 714 impl DeliverToRead for Node { 715 fn do_work( 716 self: DArc<Self>, 717 _thread: &Thread, 718 writer: &mut BinderReturnWriter<'_>, 719 ) -> Result<bool> { 720 let mut owner_inner = self.owner.inner.lock(); 721 let inner = self.inner.access_mut(&mut owner_inner); 722 723 assert!(inner.delivery_state.has_pushed_node); 724 if inner.delivery_state.has_pushed_wrapper { 725 // If the wrapper is scheduled, then we are either a normal push or weak zero2one 726 // increment, and the wrapper is a strong zero2one increment, so the wrapper always 727 // takes precedence over us. 728 assert!(inner.delivery_state.has_strong_zero2one); 729 inner.delivery_state.has_pushed_node = false; 730 inner.delivery_state.has_weak_zero2one = false; 731 return Ok(true); 732 } 733 734 inner.delivery_state.has_pushed_node = false; 735 inner.delivery_state.has_weak_zero2one = false; 736 inner.delivery_state.has_strong_zero2one = false; 737 738 self.do_work_locked(writer, owner_inner) 739 } 740 741 fn cancel(self: DArc<Self>) { 742 let _drop_outside_lock; 743 let mut owner_inner = self.owner.inner.lock(); 744 745 // We only do something on BINDER_THREAD_EXIT, not process exit. 746 if owner_inner.is_dead { 747 return; 748 } 749 750 // If BINDER_THREAD_EXIT is invoked on a thread with a pending node refcount update, we 751 // should move ourselves to ensure the refcount update is still delivered. 752 if let Some(node) = ListArc::try_from_arc_borrow(self.as_arc_borrow()) { 753 _drop_outside_lock = owner_inner.push_work(&self.owner, node); 754 } 755 } 756 757 fn should_sync_wakeup(&self) -> bool { 758 false 759 } 760 761 #[inline(never)] 762 fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> { 763 seq_print!( 764 m, 765 "{}node work {}: u{:016x} c{:016x}\n", 766 prefix, 767 self.debug_id, 768 self.ptr, 769 self.cookie, 770 ); 771 Ok(()) 772 } 773 } 774 775 /// Represents something that holds one or more ref-counts to a `Node`. 776 /// 777 /// Whenever process A holds a refcount to a node owned by a different process B, then process A 778 /// will store a `NodeRef` that refers to the `Node` in process B. When process A releases the 779 /// refcount, we destroy the NodeRef, which decrements the ref-count in process A. 780 /// 781 /// This type is also used for some other cases. For example, a transaction allocation holds a 782 /// refcount on the target node, and this is implemented by storing a `NodeRef` in the allocation 783 /// so that the destructor of the allocation will drop a refcount of the `Node`. 784 pub(crate) struct NodeRef { 785 pub(crate) node: DArc<Node>, 786 /// How many times does this NodeRef hold a refcount on the Node? 787 strong_node_count: usize, 788 weak_node_count: usize, 789 /// How many times does userspace hold a refcount on this NodeRef? 790 strong_count: usize, 791 weak_count: usize, 792 } 793 794 impl NodeRef { 795 pub(crate) fn new(node: DArc<Node>, strong_count: usize, weak_count: usize) -> Self { 796 Self { 797 node, 798 strong_node_count: strong_count, 799 weak_node_count: weak_count, 800 strong_count, 801 weak_count, 802 } 803 } 804 805 pub(crate) fn absorb(&mut self, mut other: Self) { 806 assert!( 807 Arc::ptr_eq(&self.node, &other.node), 808 "absorb called with differing nodes" 809 ); 810 self.strong_node_count += other.strong_node_count; 811 self.weak_node_count += other.weak_node_count; 812 self.strong_count += other.strong_count; 813 self.weak_count += other.weak_count; 814 other.strong_count = 0; 815 other.weak_count = 0; 816 other.strong_node_count = 0; 817 other.weak_node_count = 0; 818 819 if self.strong_node_count >= 2 || self.weak_node_count >= 2 { 820 let mut guard = self.node.owner.inner.lock(); 821 let inner = self.node.inner.access_mut(&mut guard); 822 823 if self.strong_node_count >= 2 { 824 inner.strong.count -= self.strong_node_count - 1; 825 self.strong_node_count = 1; 826 assert_ne!(inner.strong.count, 0); 827 } 828 if self.weak_node_count >= 2 { 829 inner.weak.count -= self.weak_node_count - 1; 830 self.weak_node_count = 1; 831 assert_ne!(inner.weak.count, 0); 832 } 833 } 834 } 835 836 pub(crate) fn get_count(&self) -> (usize, usize) { 837 (self.strong_count, self.weak_count) 838 } 839 840 pub(crate) fn clone(&self, strong: bool) -> Result<NodeRef> { 841 if strong && self.strong_count == 0 { 842 binder_debug!(UserError, "tried to use weak ref as strong ref"); 843 return Err(EINVAL); 844 } 845 Ok(self 846 .node 847 .owner 848 .inner 849 .lock() 850 .new_node_ref(self.node.clone(), strong, None)) 851 } 852 853 /// Updates (increments or decrements) the number of references held against the node. If the 854 /// count being updated transitions from 0 to 1 or from 1 to 0, the node is notified by having 855 /// its `update_refcount` function called. 856 /// 857 /// Returns whether `self` should be removed (when both counts are zero). 858 pub(crate) fn update(&mut self, inc: bool, strong: bool) -> bool { 859 if strong && self.strong_count == 0 { 860 return false; 861 } 862 let (count, node_count, other_count) = if strong { 863 ( 864 &mut self.strong_count, 865 &mut self.strong_node_count, 866 self.weak_count, 867 ) 868 } else { 869 ( 870 &mut self.weak_count, 871 &mut self.weak_node_count, 872 self.strong_count, 873 ) 874 }; 875 if inc { 876 if *count == 0 { 877 *node_count = 1; 878 self.node.update_refcount(true, 1, strong); 879 } 880 *count += 1; 881 } else { 882 if *count == 0 { 883 binder_debug!( 884 UserError, 885 "performed invalid {} decrement on ref", 886 if strong { "strong" } else { "weak" } 887 ); 888 return false; 889 } 890 *count -= 1; 891 if *count == 0 { 892 self.node.update_refcount(false, *node_count, strong); 893 *node_count = 0; 894 return other_count == 0; 895 } 896 } 897 false 898 } 899 } 900 901 impl Drop for NodeRef { 902 // This destructor is called conditionally from `Allocation::drop`. That branch is often 903 // mispredicted. Inlining this method call reduces the cost of those branch mispredictions. 904 #[inline(always)] 905 fn drop(&mut self) { 906 if self.strong_node_count > 0 { 907 self.node 908 .update_refcount(false, self.strong_node_count, true); 909 } 910 if self.weak_node_count > 0 { 911 self.node 912 .update_refcount(false, self.weak_node_count, false); 913 } 914 } 915 } 916 917 struct NodeDeathInner { 918 dead: bool, 919 cleared: bool, 920 notification_done: bool, 921 /// Indicates whether the normal flow was interrupted by removing the handle. In this case, we 922 /// need behave as if the death notification didn't exist (i.e., we don't deliver anything to 923 /// the user. 924 aborted: bool, 925 } 926 927 /// Used to deliver notifications when a process dies. 928 /// 929 /// A process can request to be notified when a process dies using `BC_REQUEST_DEATH_NOTIFICATION`. 930 /// This will make the driver send a `BR_DEAD_BINDER` to userspace when the process dies (or 931 /// immediately if it is already dead). Userspace is supposed to respond with `BC_DEAD_BINDER_DONE` 932 /// once it has processed the notification. 933 /// 934 /// Userspace can unregister from death notifications using the `BC_CLEAR_DEATH_NOTIFICATION` 935 /// command. In this case, the kernel will respond with `BR_CLEAR_DEATH_NOTIFICATION_DONE` once the 936 /// notification has been removed. Note that if the remote process dies before the kernel has 937 /// responded with `BR_CLEAR_DEATH_NOTIFICATION_DONE`, then the kernel will still send a 938 /// `BR_DEAD_BINDER`, which userspace must be able to process. In this case, the kernel will wait 939 /// for the `BC_DEAD_BINDER_DONE` command before it sends `BR_CLEAR_DEATH_NOTIFICATION_DONE`. 940 /// 941 /// Note that even if the kernel sends a `BR_DEAD_BINDER`, this does not remove the death 942 /// notification. Userspace must still remove it manually using `BC_CLEAR_DEATH_NOTIFICATION`. 943 /// 944 /// If a process uses `BC_RELEASE` to destroy its last refcount on a node that has an active death 945 /// registration, then the death registration is immediately deleted (we implement this using the 946 /// `aborted` field). However, userspace is not supposed to delete a `NodeRef` without first 947 /// deregistering death notifications, so this codepath is not executed under normal circumstances. 948 #[pin_data] 949 pub(crate) struct NodeDeath { 950 node: DArc<Node>, 951 process: Arc<Process>, 952 pub(crate) cookie: u64, 953 #[pin] 954 links_track: AtomicTracker<0>, 955 /// Used by the owner `Node` to store a list of registered death notifications. 956 /// 957 /// # Invariants 958 /// 959 /// Only ever used with the `death_list` list of `self.node`. 960 #[pin] 961 death_links: ListLinks<1>, 962 /// Used by the process to keep track of the death notifications for which we have sent a 963 /// `BR_DEAD_BINDER` but not yet received a `BC_DEAD_BINDER_DONE`. 964 /// 965 /// # Invariants 966 /// 967 /// Only ever used with the `delivered_deaths` list of `self.process`. 968 #[pin] 969 delivered_links: ListLinks<2>, 970 #[pin] 971 delivered_links_track: AtomicTracker<2>, 972 #[pin] 973 inner: SpinLock<NodeDeathInner>, 974 } 975 976 impl NodeDeath { 977 /// Constructs a new node death notification object. 978 pub(crate) fn new( 979 node: DArc<Node>, 980 process: Arc<Process>, 981 cookie: u64, 982 ) -> impl PinInit<DTRWrap<Self>> { 983 DTRWrap::new(pin_init!( 984 Self { 985 node, 986 process, 987 cookie, 988 links_track <- AtomicTracker::new(), 989 death_links <- ListLinks::new(), 990 delivered_links <- ListLinks::new(), 991 delivered_links_track <- AtomicTracker::new(), 992 inner <- kernel::new_spinlock!(NodeDeathInner { 993 dead: false, 994 cleared: false, 995 notification_done: false, 996 aborted: false, 997 }, "NodeDeath::inner"), 998 } 999 )) 1000 } 1001 1002 /// Sets the cleared flag to `true`. 1003 /// 1004 /// It removes `self` from the node's death notification list if needed. 1005 /// 1006 /// Returns whether it needs to be queued. 1007 pub(crate) fn set_cleared(self: &DArc<Self>, abort: bool) -> bool { 1008 let (needs_removal, needs_queueing) = { 1009 // Update state and determine if we need to queue a work item. We only need to do it 1010 // when the node is not dead or if the user already completed the death notification. 1011 let mut inner = self.inner.lock(); 1012 if abort { 1013 inner.aborted = true; 1014 } 1015 if inner.cleared { 1016 // Already cleared. 1017 return false; 1018 } 1019 inner.cleared = true; 1020 (!inner.dead, !inner.dead || inner.notification_done) 1021 }; 1022 1023 // Remove death notification from node. 1024 if needs_removal { 1025 let mut owner_inner = self.node.owner.inner.lock(); 1026 let node_inner = self.node.inner.access_mut(&mut owner_inner); 1027 // SAFETY: A `NodeDeath` is never inserted into the death list of any node other than 1028 // its owner, so it is either in this death list or in no death list. 1029 unsafe { node_inner.death_list.remove(self) }; 1030 } 1031 needs_queueing 1032 } 1033 1034 /// Sets the 'notification done' flag to `true`. 1035 pub(crate) fn set_notification_done(self: DArc<Self>, thread: &Thread) { 1036 let needs_queueing = { 1037 let mut inner = self.inner.lock(); 1038 inner.notification_done = true; 1039 inner.cleared 1040 }; 1041 if needs_queueing { 1042 if let Some(death) = ListArc::try_from_arc_or_drop(self) { 1043 let _ = thread.push_work_if_looper(death); 1044 } 1045 } 1046 } 1047 1048 /// Sets the 'dead' flag to `true` and queues work item if needed. 1049 pub(crate) fn set_dead(self: DArc<Self>) { 1050 let needs_queueing = { 1051 let mut inner = self.inner.lock(); 1052 if inner.cleared { 1053 false 1054 } else { 1055 inner.dead = true; 1056 true 1057 } 1058 }; 1059 if needs_queueing { 1060 // Push the death notification to the target process. There is nothing else to do if 1061 // it's already dead. 1062 if let Some(death) = ListArc::try_from_arc_or_drop(self) { 1063 let process = death.process.clone(); 1064 let _ = process.push_work(death); 1065 } 1066 } 1067 } 1068 } 1069 1070 kernel::list::impl_list_arc_safe! { 1071 impl ListArcSafe<0> for NodeDeath { 1072 tracked_by links_track: AtomicTracker; 1073 } 1074 } 1075 1076 kernel::list::impl_list_arc_safe! { 1077 impl ListArcSafe<1> for DTRWrap<NodeDeath> { untracked; } 1078 } 1079 kernel::list::impl_list_item! { 1080 impl ListItem<1> for DTRWrap<NodeDeath> { 1081 using ListLinks { self.wrapped.death_links }; 1082 } 1083 } 1084 1085 kernel::list::impl_list_arc_safe! { 1086 impl ListArcSafe<2> for DTRWrap<NodeDeath> { 1087 tracked_by wrapped: NodeDeath; 1088 } 1089 } 1090 kernel::list::impl_list_arc_safe! { 1091 impl ListArcSafe<2> for NodeDeath { 1092 tracked_by delivered_links_track: AtomicTracker<2>; 1093 } 1094 } 1095 kernel::list::impl_list_item! { 1096 impl ListItem<2> for DTRWrap<NodeDeath> { 1097 using ListLinks { self.wrapped.delivered_links }; 1098 } 1099 } 1100 1101 impl DeliverToRead for NodeDeath { 1102 fn do_work( 1103 self: DArc<Self>, 1104 _thread: &Thread, 1105 writer: &mut BinderReturnWriter<'_>, 1106 ) -> Result<bool> { 1107 let done = { 1108 let inner = self.inner.lock(); 1109 if inner.aborted { 1110 return Ok(true); 1111 } 1112 inner.cleared && (!inner.dead || inner.notification_done) 1113 }; 1114 1115 let cookie = self.cookie; 1116 let cmd = if done { 1117 BR_CLEAR_DEATH_NOTIFICATION_DONE 1118 } else { 1119 let process = self.process.clone(); 1120 let mut process_inner = process.inner.lock(); 1121 let inner = self.inner.lock(); 1122 if inner.aborted { 1123 return Ok(true); 1124 } 1125 // We're still holding the inner lock, so it cannot be aborted while we insert it into 1126 // the delivered list. 1127 process_inner.death_delivered(self.clone()); 1128 binder_debug!( 1129 DeathNotification, 1130 "sending death notification, cookie {:016x}", 1131 cookie 1132 ); 1133 BR_DEAD_BINDER 1134 }; 1135 1136 writer.write_code(cmd)?; 1137 writer.write_payload(&cookie)?; 1138 // DEAD_BINDER notifications can cause transactions, so stop processing work items when we 1139 // get to a death notification. 1140 Ok(cmd != BR_DEAD_BINDER) 1141 } 1142 1143 fn cancel(self: DArc<Self>) { 1144 binder_debug!( 1145 pid = self.process.task.pid(), 1146 DeadTransaction, 1147 "undelivered death notification, {:016x}", 1148 self.cookie 1149 ); 1150 } 1151 1152 fn should_sync_wakeup(&self) -> bool { 1153 false 1154 } 1155 1156 #[inline(never)] 1157 fn debug_print(&self, m: &SeqFile, prefix: &str, _tprefix: &str) -> Result<()> { 1158 let inner = self.inner.lock(); 1159 1160 let dead_binder = inner.dead && !inner.notification_done; 1161 1162 if dead_binder { 1163 if inner.cleared { 1164 seq_print!(m, "{}has cleared dead binder\n", prefix); 1165 } else { 1166 seq_print!(m, "{}has dead binder\n", prefix); 1167 } 1168 } else { 1169 seq_print!(m, "{}has cleared death notification\n", prefix); 1170 } 1171 1172 Ok(()) 1173 } 1174 } 1175