xref: /DragonOS/kernel/src/namespaces/pid_namespace.rs (revision f5b2038871d3441e1c7f32439ff422957e7ab828)
1*f5b20388Scodeironman #![allow(dead_code, unused_variables, unused_imports)]
2*f5b20388Scodeironman use alloc::vec::Vec;
3*f5b20388Scodeironman 
4*f5b20388Scodeironman use super::namespace::Namespace;
5*f5b20388Scodeironman use super::ucount::Ucount::PidNamespaces;
6*f5b20388Scodeironman use super::NsSet;
7*f5b20388Scodeironman use super::{namespace::NsCommon, ucount::UCounts, user_namespace::UserNamespace};
8*f5b20388Scodeironman use crate::container_of;
9*f5b20388Scodeironman use crate::filesystem::vfs::{IndexNode, ROOT_INODE};
10*f5b20388Scodeironman use crate::namespaces::namespace::NsOperations;
11*f5b20388Scodeironman use crate::process::fork::CloneFlags;
12*f5b20388Scodeironman use crate::process::ProcessManager;
13*f5b20388Scodeironman use crate::syscall::Syscall;
14*f5b20388Scodeironman use crate::{libs::rwlock::RwLock, process::Pid};
15*f5b20388Scodeironman use alloc::boxed::Box;
16*f5b20388Scodeironman use alloc::string::String;
17*f5b20388Scodeironman use alloc::string::ToString;
18*f5b20388Scodeironman use alloc::sync::Arc;
19*f5b20388Scodeironman use ida::IdAllocator;
20*f5b20388Scodeironman use system_error::SystemError;
21*f5b20388Scodeironman use system_error::SystemError::ENOSPC;
22*f5b20388Scodeironman 
23*f5b20388Scodeironman const INT16_MAX: u32 = 32767;
24*f5b20388Scodeironman const MAX_PID_NS_LEVEL: usize = 32;
25*f5b20388Scodeironman const PIDNS_ADDING: u32 = 1 << 31;
26*f5b20388Scodeironman const PID_MAX: usize = 4096;
27*f5b20388Scodeironman static PID_IDA: ida::IdAllocator = ida::IdAllocator::new(1, usize::MAX).unwrap();
28*f5b20388Scodeironman #[derive(Debug)]
29*f5b20388Scodeironman #[repr(C)]
30*f5b20388Scodeironman pub struct PidNamespace {
31*f5b20388Scodeironman     id_alloctor: RwLock<IdAllocator>,
32*f5b20388Scodeironman     /// 已经分配的进程数
33*f5b20388Scodeironman     pid_allocated: u32,
34*f5b20388Scodeironman     /// 当前的pid_namespace所在的层数
35*f5b20388Scodeironman     pub level: usize,
36*f5b20388Scodeironman     /// 父命名空间
37*f5b20388Scodeironman     parent: Option<Arc<PidNamespace>>,
38*f5b20388Scodeironman     /// 资源计数器
39*f5b20388Scodeironman     ucounts: Arc<UCounts>,
40*f5b20388Scodeironman     /// 关联的用户namespace
41*f5b20388Scodeironman     user_ns: Arc<UserNamespace>,
42*f5b20388Scodeironman     /// 回收孤儿进程的init进程
43*f5b20388Scodeironman     child_reaper: Arc<RwLock<Pid>>,
44*f5b20388Scodeironman     /// namespace共有部分
45*f5b20388Scodeironman     pub ns_common: Arc<NsCommon>,
46*f5b20388Scodeironman }
47*f5b20388Scodeironman 
48*f5b20388Scodeironman impl Default for PidNamespace {
default() -> Self49*f5b20388Scodeironman     fn default() -> Self {
50*f5b20388Scodeironman         Self::new()
51*f5b20388Scodeironman     }
52*f5b20388Scodeironman }
53*f5b20388Scodeironman 
54*f5b20388Scodeironman #[derive(Debug, Clone)]
55*f5b20388Scodeironman pub struct PidStrcut {
56*f5b20388Scodeironman     pub level: usize,
57*f5b20388Scodeironman     pub numbers: Vec<UPid>,
58*f5b20388Scodeironman     pub stashed: Arc<dyn IndexNode>,
59*f5b20388Scodeironman }
60*f5b20388Scodeironman 
61*f5b20388Scodeironman impl Default for PidStrcut {
default() -> Self62*f5b20388Scodeironman     fn default() -> Self {
63*f5b20388Scodeironman         Self::new()
64*f5b20388Scodeironman     }
65*f5b20388Scodeironman }
66*f5b20388Scodeironman #[derive(Debug, Clone)]
67*f5b20388Scodeironman pub struct UPid {
68*f5b20388Scodeironman     pub nr: Pid, // 在该pid_namespace 中的pid
69*f5b20388Scodeironman     pub ns: Arc<PidNamespace>,
70*f5b20388Scodeironman }
71*f5b20388Scodeironman 
72*f5b20388Scodeironman impl PidStrcut {
new() -> Self73*f5b20388Scodeironman     pub fn new() -> Self {
74*f5b20388Scodeironman         Self {
75*f5b20388Scodeironman             level: 0,
76*f5b20388Scodeironman             numbers: vec![UPid {
77*f5b20388Scodeironman                 nr: Pid::new(0),
78*f5b20388Scodeironman                 ns: Arc::new(PidNamespace::new()),
79*f5b20388Scodeironman             }],
80*f5b20388Scodeironman             stashed: ROOT_INODE(),
81*f5b20388Scodeironman         }
82*f5b20388Scodeironman     }
83*f5b20388Scodeironman 
put_pid(pid: PidStrcut)84*f5b20388Scodeironman     pub fn put_pid(pid: PidStrcut) {
85*f5b20388Scodeironman         let ns = pid.numbers[pid.level].ns.clone();
86*f5b20388Scodeironman         let id = pid.numbers[pid.level].nr.data();
87*f5b20388Scodeironman         ns.id_alloctor.write().free(id);
88*f5b20388Scodeironman     }
alloc_pid(ns: Arc<PidNamespace>, set_tid: Vec<usize>) -> Result<PidStrcut, SystemError>89*f5b20388Scodeironman     pub fn alloc_pid(ns: Arc<PidNamespace>, set_tid: Vec<usize>) -> Result<PidStrcut, SystemError> {
90*f5b20388Scodeironman         let mut set_tid_size = set_tid.len();
91*f5b20388Scodeironman         if set_tid_size > ns.level + 1 {
92*f5b20388Scodeironman             return Err(SystemError::EINVAL);
93*f5b20388Scodeironman         }
94*f5b20388Scodeironman 
95*f5b20388Scodeironman         let mut numbers = Vec::<UPid>::with_capacity(ns.level + 1);
96*f5b20388Scodeironman         let mut tid_iter = set_tid.into_iter().rev();
97*f5b20388Scodeironman         let mut pid_ns = ns.clone(); // 当前正在处理的命名空间
98*f5b20388Scodeironman         for i in (0..=ns.level).rev() {
99*f5b20388Scodeironman             let tid = tid_iter.next().unwrap_or(0);
100*f5b20388Scodeironman             if set_tid_size > 0 {
101*f5b20388Scodeironman                 if tid < 1 || tid > INT16_MAX as usize {
102*f5b20388Scodeironman                     return Err(SystemError::EINVAL);
103*f5b20388Scodeironman                 }
104*f5b20388Scodeironman                 set_tid_size -= 1;
105*f5b20388Scodeironman             }
106*f5b20388Scodeironman             let mut nr = tid;
107*f5b20388Scodeironman 
108*f5b20388Scodeironman             if tid == 0 {
109*f5b20388Scodeironman                 nr = pid_ns
110*f5b20388Scodeironman                     .id_alloctor
111*f5b20388Scodeironman                     .write()
112*f5b20388Scodeironman                     .alloc()
113*f5b20388Scodeironman                     .expect("PID allocation failed.");
114*f5b20388Scodeironman             }
115*f5b20388Scodeironman 
116*f5b20388Scodeironman             numbers.insert(
117*f5b20388Scodeironman                 i,
118*f5b20388Scodeironman                 UPid {
119*f5b20388Scodeironman                     nr: Pid::from(nr),
120*f5b20388Scodeironman                     ns: pid_ns.clone(),
121*f5b20388Scodeironman                 },
122*f5b20388Scodeironman             );
123*f5b20388Scodeironman 
124*f5b20388Scodeironman             if let Some(parent_ns) = &pid_ns.parent {
125*f5b20388Scodeironman                 pid_ns = parent_ns.clone();
126*f5b20388Scodeironman             } else {
127*f5b20388Scodeironman                 break; // 根命名空间,无需继续向上。
128*f5b20388Scodeironman             }
129*f5b20388Scodeironman         }
130*f5b20388Scodeironman         Ok(PidStrcut {
131*f5b20388Scodeironman             level: ns.level,
132*f5b20388Scodeironman             numbers,
133*f5b20388Scodeironman             stashed: ROOT_INODE(),
134*f5b20388Scodeironman         })
135*f5b20388Scodeironman     }
136*f5b20388Scodeironman 
ns_of_pid(&self) -> Arc<PidNamespace>137*f5b20388Scodeironman     pub fn ns_of_pid(&self) -> Arc<PidNamespace> {
138*f5b20388Scodeironman         self.numbers[self.level].ns.clone()
139*f5b20388Scodeironman     }
140*f5b20388Scodeironman }
141*f5b20388Scodeironman #[derive(Debug)]
142*f5b20388Scodeironman struct PidNsOperations {
143*f5b20388Scodeironman     name: String,
144*f5b20388Scodeironman     clone_flags: CloneFlags,
145*f5b20388Scodeironman }
146*f5b20388Scodeironman impl PidNsOperations {
new(name: String) -> Self147*f5b20388Scodeironman     pub fn new(name: String) -> Self {
148*f5b20388Scodeironman         Self {
149*f5b20388Scodeironman             name,
150*f5b20388Scodeironman             clone_flags: CloneFlags::CLONE_NEWPID,
151*f5b20388Scodeironman         }
152*f5b20388Scodeironman     }
153*f5b20388Scodeironman }
154*f5b20388Scodeironman impl Namespace for PidNamespace {
ns_common_to_ns(ns_common: Arc<NsCommon>) -> Arc<Self>155*f5b20388Scodeironman     fn ns_common_to_ns(ns_common: Arc<NsCommon>) -> Arc<Self> {
156*f5b20388Scodeironman         container_of!(Arc::as_ptr(&ns_common), PidNamespace, ns_common)
157*f5b20388Scodeironman     }
158*f5b20388Scodeironman }
159*f5b20388Scodeironman 
160*f5b20388Scodeironman impl NsOperations for PidNsOperations {
put(&self, ns_common: Arc<NsCommon>)161*f5b20388Scodeironman     fn put(&self, ns_common: Arc<NsCommon>) {
162*f5b20388Scodeironman         let _pid_ns = PidNamespace::ns_common_to_ns(ns_common);
163*f5b20388Scodeironman         // pid_ns 超出作用域自动drop 同时递归drop
164*f5b20388Scodeironman     }
165*f5b20388Scodeironman 
owner(&self, ns_common: Arc<NsCommon>) -> Arc<UserNamespace>166*f5b20388Scodeironman     fn owner(&self, ns_common: Arc<NsCommon>) -> Arc<UserNamespace> {
167*f5b20388Scodeironman         let pid_ns = PidNamespace::ns_common_to_ns(ns_common);
168*f5b20388Scodeironman         pid_ns.user_ns.clone()
169*f5b20388Scodeironman     }
170*f5b20388Scodeironman 
get_parent(&self, ns_common: Arc<NsCommon>) -> Result<Arc<NsCommon>, SystemError>171*f5b20388Scodeironman     fn get_parent(&self, ns_common: Arc<NsCommon>) -> Result<Arc<NsCommon>, SystemError> {
172*f5b20388Scodeironman         let current = ProcessManager::current_pid();
173*f5b20388Scodeironman         let pcb = ProcessManager::find(current).unwrap();
174*f5b20388Scodeironman         let active = pcb.pid_strcut().read().ns_of_pid();
175*f5b20388Scodeironman         let mut pid_ns = &PidNamespace::ns_common_to_ns(ns_common).parent;
176*f5b20388Scodeironman 
177*f5b20388Scodeironman         while let Some(ns) = pid_ns {
178*f5b20388Scodeironman             if Arc::ptr_eq(&active, ns) {
179*f5b20388Scodeironman                 return Ok(ns.ns_common.clone());
180*f5b20388Scodeironman             }
181*f5b20388Scodeironman             pid_ns = &ns.parent;
182*f5b20388Scodeironman         }
183*f5b20388Scodeironman         Err(SystemError::EPERM)
184*f5b20388Scodeironman     }
185*f5b20388Scodeironman 
get(&self, pid: Pid) -> Option<Arc<NsCommon>>186*f5b20388Scodeironman     fn get(&self, pid: Pid) -> Option<Arc<NsCommon>> {
187*f5b20388Scodeironman         let pcb = ProcessManager::find(pid);
188*f5b20388Scodeironman         pcb.map(|pcb| pcb.get_nsproxy().read().pid_namespace.ns_common.clone())
189*f5b20388Scodeironman     }
install(&self, nsset: &mut NsSet, ns_common: Arc<NsCommon>) -> Result<(), SystemError>190*f5b20388Scodeironman     fn install(&self, nsset: &mut NsSet, ns_common: Arc<NsCommon>) -> Result<(), SystemError> {
191*f5b20388Scodeironman         let nsproxy = &mut nsset.nsproxy;
192*f5b20388Scodeironman         let current = ProcessManager::current_pid();
193*f5b20388Scodeironman         let pcb = ProcessManager::find(current).unwrap();
194*f5b20388Scodeironman         let active = pcb.pid_strcut().read().ns_of_pid();
195*f5b20388Scodeironman         let mut pid_ns = PidNamespace::ns_common_to_ns(ns_common);
196*f5b20388Scodeironman         if pid_ns.level < active.level {
197*f5b20388Scodeironman             return Err(SystemError::EINVAL);
198*f5b20388Scodeironman         }
199*f5b20388Scodeironman         while pid_ns.level > active.level {
200*f5b20388Scodeironman             if let Some(ns) = &pid_ns.parent {
201*f5b20388Scodeironman                 pid_ns = ns.clone();
202*f5b20388Scodeironman             } else {
203*f5b20388Scodeironman                 break;
204*f5b20388Scodeironman             }
205*f5b20388Scodeironman         }
206*f5b20388Scodeironman         if Arc::ptr_eq(&pid_ns, &active) {
207*f5b20388Scodeironman             return Err(SystemError::EINVAL);
208*f5b20388Scodeironman         }
209*f5b20388Scodeironman         nsproxy.pid_namespace = pid_ns.clone();
210*f5b20388Scodeironman         Ok(())
211*f5b20388Scodeironman     }
212*f5b20388Scodeironman }
213*f5b20388Scodeironman impl PidNamespace {
new() -> Self214*f5b20388Scodeironman     pub fn new() -> Self {
215*f5b20388Scodeironman         Self {
216*f5b20388Scodeironman             id_alloctor: RwLock::new(IdAllocator::new(1, PID_MAX).unwrap()),
217*f5b20388Scodeironman             pid_allocated: 1,
218*f5b20388Scodeironman             level: 0,
219*f5b20388Scodeironman             child_reaper: Arc::new(RwLock::new(Pid::from(1))),
220*f5b20388Scodeironman             parent: None,
221*f5b20388Scodeironman             ucounts: Arc::new(UCounts::new()),
222*f5b20388Scodeironman             user_ns: Arc::new(UserNamespace::new()),
223*f5b20388Scodeironman             ns_common: Arc::new(NsCommon::new(Box::new(PidNsOperations::new(
224*f5b20388Scodeironman                 "pid".to_string(),
225*f5b20388Scodeironman             )))),
226*f5b20388Scodeironman         }
227*f5b20388Scodeironman     }
228*f5b20388Scodeironman 
create_pid_namespace( &self, parent: Arc<PidNamespace>, user_ns: Arc<UserNamespace>, ) -> Result<Self, SystemError>229*f5b20388Scodeironman     pub fn create_pid_namespace(
230*f5b20388Scodeironman         &self,
231*f5b20388Scodeironman         parent: Arc<PidNamespace>,
232*f5b20388Scodeironman         user_ns: Arc<UserNamespace>,
233*f5b20388Scodeironman     ) -> Result<Self, SystemError> {
234*f5b20388Scodeironman         let level = parent.level + 1;
235*f5b20388Scodeironman         if level > MAX_PID_NS_LEVEL {
236*f5b20388Scodeironman             return Err(ENOSPC);
237*f5b20388Scodeironman         }
238*f5b20388Scodeironman         let ucounts = self.inc_pid_namespaces(user_ns.clone())?;
239*f5b20388Scodeironman 
240*f5b20388Scodeironman         if ucounts.is_none() {
241*f5b20388Scodeironman             return Err(SystemError::ENOSPC);
242*f5b20388Scodeironman         }
243*f5b20388Scodeironman         let ucounts = ucounts.unwrap();
244*f5b20388Scodeironman 
245*f5b20388Scodeironman         let ns_common = Arc::new(NsCommon::new(Box::new(PidNsOperations::new(
246*f5b20388Scodeironman             "pid".to_string(),
247*f5b20388Scodeironman         ))));
248*f5b20388Scodeironman         let child_reaper = parent.child_reaper.clone();
249*f5b20388Scodeironman         Ok(Self {
250*f5b20388Scodeironman             id_alloctor: RwLock::new(IdAllocator::new(1, PID_MAX).unwrap()),
251*f5b20388Scodeironman             pid_allocated: PIDNS_ADDING,
252*f5b20388Scodeironman             level,
253*f5b20388Scodeironman             ucounts,
254*f5b20388Scodeironman             parent: Some(parent),
255*f5b20388Scodeironman             user_ns,
256*f5b20388Scodeironman             ns_common,
257*f5b20388Scodeironman             child_reaper,
258*f5b20388Scodeironman         })
259*f5b20388Scodeironman     }
260*f5b20388Scodeironman 
inc_pid_namespaces( &self, user_ns: Arc<UserNamespace>, ) -> Result<Option<Arc<UCounts>>, SystemError>261*f5b20388Scodeironman     pub fn inc_pid_namespaces(
262*f5b20388Scodeironman         &self,
263*f5b20388Scodeironman         user_ns: Arc<UserNamespace>,
264*f5b20388Scodeironman     ) -> Result<Option<Arc<UCounts>>, SystemError> {
265*f5b20388Scodeironman         Ok(self
266*f5b20388Scodeironman             .ucounts
267*f5b20388Scodeironman             .inc_ucounts(user_ns, Syscall::geteuid()?, PidNamespaces))
268*f5b20388Scodeironman     }
269*f5b20388Scodeironman 
dec_pid_namespaces(&mut self, uc: Arc<UCounts>)270*f5b20388Scodeironman     pub fn dec_pid_namespaces(&mut self, uc: Arc<UCounts>) {
271*f5b20388Scodeironman         UCounts::dec_ucount(uc, PidNamespaces)
272*f5b20388Scodeironman     }
273*f5b20388Scodeironman }
274