1 // SPDX-License-Identifier: GPL-2.0 2 3 // Copyright (C) 2025 Google LLC. 4 5 use kernel::{ 6 alloc::kvec::KVVec, 7 error::code::*, 8 prelude::*, 9 security, 10 str::{CStr, CString}, 11 sync::{Arc, Mutex}, 12 task::Kuid, 13 }; 14 15 use crate::{error::BinderError, node::NodeRef, process::Process}; 16 17 kernel::sync::global_lock! { 18 // SAFETY: We call `init` in the module initializer, so it's initialized before first use. 19 pub(crate) unsafe(uninit) static CONTEXTS: Mutex<ContextList> = ContextList { 20 contexts: KVVec::new(), 21 }; 22 } 23 24 pub(crate) struct ContextList { 25 contexts: KVVec<Arc<Context>>, 26 } 27 28 pub(crate) fn get_all_contexts() -> Result<KVVec<Arc<Context>>> { 29 let lock = CONTEXTS.lock(); 30 let mut ctxs = KVVec::with_capacity(lock.contexts.len(), GFP_KERNEL)?; 31 for ctx in lock.contexts.iter() { 32 ctxs.push(ctx.clone(), GFP_KERNEL)?; 33 } 34 Ok(ctxs) 35 } 36 37 /// This struct keeps track of the processes using this context, and which process is the context 38 /// manager. 39 struct Manager { 40 node: Option<NodeRef>, 41 uid: Option<Kuid>, 42 all_procs: KVVec<Arc<Process>>, 43 } 44 45 /// There is one context per binder file (/dev/binder, /dev/hwbinder, etc) 46 #[pin_data] 47 pub(crate) struct Context { 48 #[pin] 49 manager: Mutex<Manager>, 50 pub(crate) name: CString, 51 } 52 53 impl Context { 54 pub(crate) fn new(name: &CStr) -> Result<Arc<Self>> { 55 let name = CString::try_from(name)?; 56 let ctx = Arc::pin_init( 57 try_pin_init!(Context { 58 name, 59 manager <- kernel::new_mutex!(Manager { 60 all_procs: KVVec::new(), 61 node: None, 62 uid: None, 63 }, "Context::manager"), 64 }), 65 GFP_KERNEL, 66 )?; 67 68 CONTEXTS.lock().contexts.push(ctx.clone(), GFP_KERNEL)?; 69 70 Ok(ctx) 71 } 72 73 /// Called when the file for this context is unlinked. 74 /// 75 /// No-op if called twice. 76 pub(crate) fn deregister(self: &Arc<Self>) { 77 // Safe removal using retain 78 CONTEXTS.lock().contexts.retain(|c| !Arc::ptr_eq(c, self)); 79 } 80 81 pub(crate) fn register_process(self: &Arc<Self>, proc: Arc<Process>) -> Result { 82 if !Arc::ptr_eq(self, &proc.ctx) { 83 pr_err!("Context::register_process called on the wrong context."); 84 return Err(EINVAL); 85 } 86 self.manager.lock().all_procs.push(proc, GFP_KERNEL)?; 87 Ok(()) 88 } 89 90 pub(crate) fn deregister_process(self: &Arc<Self>, proc: &Arc<Process>) { 91 if !Arc::ptr_eq(self, &proc.ctx) { 92 pr_err!("Context::deregister_process called on the wrong context."); 93 return; 94 } 95 let mut manager = self.manager.lock(); 96 manager.all_procs.retain(|p| !Arc::ptr_eq(p, proc)); 97 98 // Shrink the vector if it has significant unused capacity to avoid memory waste, 99 // but use a conservative strategy to prevent shrink-then-regrow oscillation. 100 // Only shrink when length drops below 1/4 of capacity, and shrink to twice the length. 101 let len = manager.all_procs.len(); 102 let cap = manager.all_procs.capacity(); 103 if len < cap / 4 { 104 // Shrink to twice the current length. Ignore allocation failures since this 105 // is just an optimization; the vector remains valid even if shrinking fails. 106 let _ = manager.all_procs.shrink_to(len * 2, GFP_KERNEL); 107 } 108 } 109 110 pub(crate) fn set_manager_node(&self, node_ref: NodeRef) -> Result { 111 let mut manager = self.manager.lock(); 112 if manager.node.is_some() { 113 pr_warn!("BINDER_SET_CONTEXT_MGR already set"); 114 return Err(EBUSY); 115 } 116 security::binder_set_context_mgr(&node_ref.node.owner.cred)?; 117 118 // If the context manager has been set before, ensure that we use the same euid. 119 let caller_uid = Kuid::current_euid(); 120 if let Some(ref uid) = manager.uid { 121 if *uid != caller_uid { 122 return Err(EPERM); 123 } 124 } 125 126 manager.node = Some(node_ref); 127 manager.uid = Some(caller_uid); 128 Ok(()) 129 } 130 131 pub(crate) fn unset_manager_node(&self) { 132 let node_ref = self.manager.lock().node.take(); 133 drop(node_ref); 134 } 135 136 pub(crate) fn get_manager_node(&self, strong: bool) -> Result<NodeRef, BinderError> { 137 self.manager 138 .lock() 139 .node 140 .as_ref() 141 .ok_or_else(BinderError::new_dead)? 142 .clone(strong) 143 .map_err(BinderError::from) 144 } 145 146 pub(crate) fn for_each_proc<F>(&self, mut func: F) 147 where 148 F: FnMut(&Process), 149 { 150 let lock = self.manager.lock(); 151 for proc in &lock.all_procs { 152 func(proc); 153 } 154 } 155 156 pub(crate) fn get_all_procs(&self) -> Result<KVVec<Arc<Process>>> { 157 let lock = self.manager.lock(); 158 let mut procs = KVVec::with_capacity(lock.all_procs.len(), GFP_KERNEL)?; 159 for proc in lock.all_procs.iter() { 160 procs.push(Arc::clone(proc), GFP_KERNEL)?; 161 } 162 Ok(procs) 163 } 164 165 pub(crate) fn get_procs_with_pid(&self, pid: i32) -> Result<KVVec<Arc<Process>>> { 166 let lock = self.manager.lock(); 167 let mut matching_procs = KVVec::new(); 168 for proc in lock.all_procs.iter() { 169 if proc.task.pid() == pid { 170 matching_procs.push(Arc::clone(proc), GFP_KERNEL)?; 171 } 172 } 173 Ok(matching_procs) 174 } 175 } 176