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