1 // SPDX-License-Identifier: GPL-2.0 2 3 // Copyright (C) 2025 Google LLC. 4 5 use kernel::{ 6 error::Error, 7 list::{List, ListArc, ListLinks}, 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 list: List::new(), 21 }; 22 } 23 24 pub(crate) struct ContextList { 25 list: List<Context>, 26 } 27 28 pub(crate) fn get_all_contexts() -> Result<KVec<Arc<Context>>> { 29 let lock = CONTEXTS.lock(); 30 31 let count = lock.list.iter().count(); 32 33 let mut ctxs = KVec::with_capacity(count, GFP_KERNEL)?; 34 for ctx in &lock.list { 35 ctxs.push(Arc::from(ctx), GFP_KERNEL)?; 36 } 37 Ok(ctxs) 38 } 39 40 /// This struct keeps track of the processes using this context, and which process is the context 41 /// manager. 42 struct Manager { 43 node: Option<NodeRef>, 44 uid: Option<Kuid>, 45 all_procs: List<Process>, 46 } 47 48 /// There is one context per binder file (/dev/binder, /dev/hwbinder, etc) 49 #[pin_data] 50 pub(crate) struct Context { 51 #[pin] 52 manager: Mutex<Manager>, 53 pub(crate) name: CString, 54 #[pin] 55 links: ListLinks, 56 } 57 58 kernel::list::impl_list_arc_safe! { 59 impl ListArcSafe<0> for Context { untracked; } 60 } 61 kernel::list::impl_list_item! { 62 impl ListItem<0> for Context { 63 using ListLinks { self.links }; 64 } 65 } 66 67 impl Context { 68 pub(crate) fn new(name: &CStr) -> Result<Arc<Self>> { 69 let name = CString::try_from(name)?; 70 let list_ctx = ListArc::pin_init::<Error>( 71 try_pin_init!(Context { 72 name, 73 links <- ListLinks::new(), 74 manager <- kernel::new_mutex!(Manager { 75 all_procs: List::new(), 76 node: None, 77 uid: None, 78 }, "Context::manager"), 79 }), 80 GFP_KERNEL, 81 )?; 82 83 let ctx = list_ctx.clone_arc(); 84 CONTEXTS.lock().list.push_back(list_ctx); 85 86 Ok(ctx) 87 } 88 89 /// Called when the file for this context is unlinked. 90 /// 91 /// No-op if called twice. 92 pub(crate) fn deregister(&self) { 93 // SAFETY: We never add the context to any other linked list than this one, so it is either 94 // in this list, or not in any list. 95 unsafe { CONTEXTS.lock().list.remove(self) }; 96 } 97 98 pub(crate) fn register_process(self: &Arc<Self>, proc: ListArc<Process>) { 99 if !Arc::ptr_eq(self, &proc.ctx) { 100 pr_err!("Context::register_process called on the wrong context."); 101 return; 102 } 103 self.manager.lock().all_procs.push_back(proc); 104 } 105 106 pub(crate) fn deregister_process(self: &Arc<Self>, proc: &Process) { 107 if !Arc::ptr_eq(self, &proc.ctx) { 108 pr_err!("Context::deregister_process called on the wrong context."); 109 return; 110 } 111 // SAFETY: We just checked that this is the right list. 112 unsafe { self.manager.lock().all_procs.remove(proc) }; 113 } 114 115 pub(crate) fn set_manager_node(&self, node_ref: NodeRef) -> Result { 116 let mut manager = self.manager.lock(); 117 if manager.node.is_some() { 118 pr_warn!("BINDER_SET_CONTEXT_MGR already set"); 119 return Err(EBUSY); 120 } 121 security::binder_set_context_mgr(&node_ref.node.owner.cred)?; 122 123 // If the context manager has been set before, ensure that we use the same euid. 124 let caller_uid = Kuid::current_euid(); 125 if let Some(ref uid) = manager.uid { 126 if *uid != caller_uid { 127 return Err(EPERM); 128 } 129 } 130 131 manager.node = Some(node_ref); 132 manager.uid = Some(caller_uid); 133 Ok(()) 134 } 135 136 pub(crate) fn unset_manager_node(&self) { 137 let node_ref = self.manager.lock().node.take(); 138 drop(node_ref); 139 } 140 141 pub(crate) fn get_manager_node(&self, strong: bool) -> Result<NodeRef, BinderError> { 142 self.manager 143 .lock() 144 .node 145 .as_ref() 146 .ok_or_else(BinderError::new_dead)? 147 .clone(strong) 148 .map_err(BinderError::from) 149 } 150 151 pub(crate) fn for_each_proc<F>(&self, mut func: F) 152 where 153 F: FnMut(&Process), 154 { 155 let lock = self.manager.lock(); 156 for proc in &lock.all_procs { 157 func(&proc); 158 } 159 } 160 161 pub(crate) fn get_all_procs(&self) -> Result<KVec<Arc<Process>>> { 162 let lock = self.manager.lock(); 163 let count = lock.all_procs.iter().count(); 164 165 let mut procs = KVec::with_capacity(count, GFP_KERNEL)?; 166 for proc in &lock.all_procs { 167 procs.push(Arc::from(proc), GFP_KERNEL)?; 168 } 169 Ok(procs) 170 } 171 172 pub(crate) fn get_procs_with_pid(&self, pid: i32) -> Result<KVec<Arc<Process>>> { 173 let orig = self.get_all_procs()?; 174 let mut backing = KVec::with_capacity(orig.len(), GFP_KERNEL)?; 175 for proc in orig.into_iter().filter(|proc| proc.task.pid() == pid) { 176 backing.push(proc, GFP_KERNEL)?; 177 } 178 Ok(backing) 179 } 180 } 181