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