From 0da2fce64a7357a7fdb878eb9080d7784cfafecf Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Mon, 8 Jul 2024 14:10:31 +0200 Subject: [PATCH] Separate context and process IDs. --- src/context/arch/x86_64.rs | 2 +- src/context/context.rs | 17 ++++++++++------- src/context/list.rs | 5 +++-- src/context/mod.rs | 8 ++++---- src/context/switch.rs | 20 ++++++++++---------- src/main.rs | 2 +- src/panic.rs | 2 +- src/ptrace.rs | 4 ++-- src/scheme/proc.rs | 25 ++++++++++++++----------- src/scheme/sys/context.rs | 2 +- src/scheme/user.rs | 4 ++-- src/sync/wait_condition.rs | 6 +++--- src/syscall/fs.rs | 4 ++-- src/syscall/process.rs | 18 +++++++++--------- 14 files changed, 63 insertions(+), 56 deletions(-) diff --git a/src/context/arch/x86_64.rs b/src/context/arch/x86_64.rs index 19904c34d7..4a8f2251b8 100644 --- a/src/context/arch/x86_64.rs +++ b/src/context/arch/x86_64.rs @@ -114,7 +114,7 @@ impl super::Context { pub fn set_userspace_io_allowed(&mut self, allowed: bool) { self.arch.userspace_io_allowed = allowed; - if self.id == super::context_id() { + if self.cid == super::current_cid() { unsafe { crate::gdt::set_userspace_io_allowed(crate::gdt::pcr(), allowed); } diff --git a/src/context/context.rs b/src/context/context.rs index f5ca0ff9f2..fb72f73d8a 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -131,8 +131,10 @@ impl Eq for WaitpidKey {} /// A context, which identifies either a process or a thread #[derive(Debug)] pub struct Context { - /// The ID of this context - pub id: ContextId, + /// The internal context ID of this context + pub cid: ContextId, + /// The process ID of this context + pub pid: ContextId, /// The group ID of this context pub pgid: ContextId, /// The ID of the parent context @@ -231,10 +233,11 @@ pub struct SignalState { } impl Context { - pub fn new(id: ContextId) -> Result { + pub fn new(cid: ContextId, pid: ContextId) -> Result { let this = Context { - id, - pgid: id, + cid, + pid, + pgid: pid, ppid: ContextId::from(0), session_id: ContextId::from(0), ruid: 0, @@ -409,7 +412,7 @@ impl Context { return addr_space; }; - if self.id == super::context_id() { + if self.cid == super::current_cid() { // TODO: Share more code with context::arch::switch_to. let this_percpu = PercpuBlock::current(); @@ -449,7 +452,7 @@ impl Context { } pub fn caller_ctx(&self) -> CallerCtx { CallerCtx { - pid: self.id.into(), + pid: self.pid.into(), uid: self.euid, gid: self.egid, } diff --git a/src/context/list.rs b/src/context/list.rs index e271052717..f7cc4e040a 100644 --- a/src/context/list.rs +++ b/src/context/list.rs @@ -50,7 +50,7 @@ impl ContextList { /// Get the current context. pub fn current(&self) -> Option<&Arc>> { - self.map.get(&super::context_id()) + self.map.get(&super::current_cid()) } pub fn iter( @@ -72,7 +72,8 @@ impl ContextList { ) -> Result<&Arc>> { assert!(self .map - .insert(id, Arc::new(RwSpinlock::new(Context::new(id)?))) + // TODO + .insert(id, Arc::new(RwSpinlock::new(Context::new(id, id)?))) .is_none()); Ok(self diff --git a/src/context/mod.rs b/src/context/mod.rs index 3dcfc5b8e0..aedbac3631 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -85,8 +85,8 @@ pub fn init() { unsafe { let percpu = PercpuBlock::current(); - percpu.switch_internals.set_context_id(context.id); - percpu.switch_internals.set_idle_id(context.id); + percpu.switch_internals.set_current_cid(context.cid); + percpu.switch_internals.set_idle_id(context.cid); } } @@ -100,8 +100,8 @@ pub fn contexts_mut() -> RwLockWriteGuard<'static, ContextList> { CONTEXTS.write() } -pub fn context_id() -> ContextId { - PercpuBlock::current().switch_internals.context_id() +pub fn current_cid() -> ContextId { + PercpuBlock::current().switch_internals.current_cid() } pub fn current() -> Result>> { diff --git a/src/context/switch.rs b/src/context/switch.rs index 79939597ed..b5e8c85a7e 100644 --- a/src/context/switch.rs +++ b/src/context/switch.rs @@ -133,11 +133,11 @@ pub fn switch() -> SwitchResult { // Locate next context for (pid, next_context_lock) in contexts // Include all contexts with IDs greater than the current... - .range((Bound::Excluded(prev_context_guard.id), Bound::Unbounded)) + .range((Bound::Excluded(prev_context_guard.cid), Bound::Unbounded)) .chain( contexts // ... and all contexts with IDs less than the current... - .range((Bound::Unbounded, Bound::Excluded(prev_context_guard.id))), + .range((Bound::Unbounded, Bound::Excluded(prev_context_guard.cid))), ) .chain( contexts @@ -184,7 +184,7 @@ pub fn switch() -> SwitchResult { next_context.switch_time = switch_time; let percpu = PercpuBlock::current(); - percpu.switch_internals.context_id.set(next_context.id); + percpu.switch_internals.current_cid.set(next_context.cid); // FIXME set th switch result in arch::switch_to instead let prev_context = @@ -201,7 +201,7 @@ pub fn switch() -> SwitchResult { })); let (ptrace_session, ptrace_flags) = if let Some((session, bp)) = ptrace::sessions() - .get(&next_context.id) + .get(&next_context.pid) .map(|s| (Arc::downgrade(s), s.data.lock().breakpoint)) { (Some(session), bp.map_or(PtraceFlags::empty(), |f| f.flags)) @@ -251,8 +251,8 @@ pub struct ContextSwitchPercpu { switch_result: Cell>, pit_ticks: Cell, - /// Unique ID of the currently running context. - context_id: Cell, + /// Unique context ID of the currently running context. + current_cid: Cell, // The ID of the idle process idle_id: Cell, @@ -260,11 +260,11 @@ pub struct ContextSwitchPercpu { pub(crate) being_sigkilled: Cell, } impl ContextSwitchPercpu { - pub fn context_id(&self) -> ContextId { - self.context_id.get() + pub fn current_cid(&self) -> ContextId { + self.current_cid.get() } - pub unsafe fn set_context_id(&self, new: ContextId) { - self.context_id.set(new) + pub unsafe fn set_current_cid(&self, new: ContextId) { + self.current_cid.set(new) } pub fn idle_id(&self) -> ContextId { self.idle_id.get() diff --git a/src/main.rs b/src/main.rs index 0417706689..add30e69d0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -263,7 +263,7 @@ pub fn ksignal(signal: usize) { "SIGNAL {}, CPU {}, PID {:?}", signal, cpu_id(), - context::context_id() + context::current_cid() ); { let contexts = context::contexts(); diff --git a/src/panic.rs b/src/panic.rs index cb0144c4e6..0e555b6e16 100644 --- a/src/panic.rs +++ b/src/panic.rs @@ -13,7 +13,7 @@ fn rust_begin_unwind(info: &PanicInfo) -> ! { interrupt::stack_trace(); } - println!("CPU {}, PID {:?}", cpu_id(), context::context_id()); + println!("CPU {}, CID {:?}", cpu_id(), context::current_cid()); // This could deadlock, but at this point we are going to halt anyways { diff --git a/src/ptrace.rs b/src/ptrace.rs index 04b28542de..ed03ea10ee 100644 --- a/src/ptrace.rs +++ b/src/ptrace.rs @@ -175,7 +175,7 @@ pub fn send_event(event: PtraceEvent) -> Option<()> { let contexts = context::contexts(); let context = contexts.current()?; let context = context.read(); - context.id + context.pid }; let sessions = sessions(); @@ -295,7 +295,7 @@ pub fn next_breakpoint() -> Option { let context = context.read(); let sessions = sessions(); - let session = sessions.get(&context.id)?; + let session = sessions.get(&context.pid)?; let data = session.data.lock(); let breakpoint = data.breakpoint?; diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index ae59f74f8e..be129279f8 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -75,7 +75,7 @@ fn try_stop_context(pid: ContextId, callback: F) -> Result where F: FnOnce(&mut Context) -> Result, { - if pid == context::context_id() { + if pid == context::current_cid() { return Err(Error::new(EBADF)); } // Stop process @@ -215,6 +215,7 @@ impl OperationData { #[derive(Clone)] struct Info { pid: ContextId, + cid: ContextId, flags: usize, // Important: Operation must never change. Search for: @@ -344,7 +345,7 @@ impl ProcScheme { let current = current.read(); // Are we the process? - if target.id != current.id { + if target.pid != current.pid { // Do we own the process? if uid != target.euid && gid != target.egid { return Err(Error::new(EPERM)); @@ -354,13 +355,13 @@ impl ProcScheme { // bypass this check. match contexts .ancestors(target.ppid) - .find(|&(id, _context)| id == current.id) + .find(|&(id, _context)| pid == current.pid) { Some((id, context)) => { // Paranoid sanity check, as ptrace security holes // wouldn't be fun - assert_eq!(id, current.id); - assert_eq!(id, context.read().id); + assert_eq!(id, current.pid); + assert_eq!(id, context.read().pid); } None => return Err(Error::new(EPERM)), } @@ -400,6 +401,7 @@ impl ProcScheme { flags, pid, operation: operation.clone(), + cid: pid, }, data, }, @@ -471,7 +473,7 @@ impl ProcScheme { #[cfg(target_arch = "x86_64")] fn read_env_regs(&self, info: &Info) -> Result { // TODO: Avoid rdmsr if fsgsbase is not enabled, if this is worth optimizing for. - let (fsbase, gsbase) = if info.pid == context::context_id() { + let (fsbase, gsbase) = if info.cid == context::current_cid() { unsafe { ( x86::msr::rdmsr(x86::msr::IA32_FS_BASE), @@ -551,7 +553,7 @@ impl ProcScheme { return Err(Error::new(EINVAL)); } - if info.pid == context::context_id() { + if info.pid == context::current_cid() { unsafe { x86::msr::wrmsr(x86::msr::IA32_FS_BASE, regs.fsbase as u64); // We have to write to KERNEL_GSBASE, because when the kernel returns to @@ -587,7 +589,7 @@ impl KernelScheme for ProcScheme { let pid_str = parts.next().ok_or(Error::new(ENOENT))?; let pid = if pid_str == "current" { - context::context_id() + context::current_cid() } else if pid_str == "new" { inherit_context()? } else if !FULL { @@ -630,7 +632,7 @@ impl KernelScheme for ProcScheme { let mut handle = HANDLES.write().remove(&id).ok_or(Error::new(EBADF))?; handle.continue_ignored_children(); - let stop_context = if handle.info.pid == context::context_id() { + let stop_context = if handle.info.cid == context::current_cid() { with_context_mut } else { try_stop_context @@ -1439,6 +1441,7 @@ impl KernelScheme for ProcScheme { info: Info { flags: 0, pid: info.pid, + cid: info.cid, operation, }, data, @@ -1578,12 +1581,12 @@ fn inherit_context() -> Result { new_context.rgid = current_context.rgid; new_context.ens = current_context.ens; new_context.rns = current_context.rns; - new_context.ppid = current_context.id; + new_context.ppid = current_context.pid; new_context.pgid = current_context.pgid; new_context.session_id = current_context.session_id; new_context.umask = current_context.umask; - new_context.id + new_context.cid }; if ptrace::send_event(crate::syscall::ptrace_event!( diff --git a/src/scheme/sys/context.rs b/src/scheme/sys/context.rs index 60c163afec..7f848a268a 100644 --- a/src/scheme/sys/context.rs +++ b/src/scheme/sys/context.rs @@ -106,7 +106,7 @@ pub fn resource() -> Result> { string.push_str(&format!( "{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<11}{:<12}{:<8}{}\n", - context.id.get(), + context.pid.get(), context.pgid.get(), context.ppid.get(), context.session_id.get(), diff --git a/src/scheme/user.rs b/src/scheme/user.rs index bd84677026..7562ebdff7 100644 --- a/src/scheme/user.rs +++ b/src/scheme/user.rs @@ -855,7 +855,7 @@ impl UserInner { 0, uid_gid_hack_merge(current_uid_gid()?), ], - caller: context::context_id().get() as u64, + caller: context::current()?.read().pid.get() as u64, }); event::trigger(self.root_id, self.handle_id, EVENT_READ); @@ -1104,7 +1104,7 @@ impl UserInner { } } let desc = desc_res?; - (context.id, desc.description) + (context.pid, desc.description) }; let response = self.call_extended_inner( diff --git a/src/sync/wait_condition.rs b/src/sync/wait_condition.rs index 927ae3c739..91b05a6582 100644 --- a/src/sync/wait_condition.rs +++ b/src/sync/wait_condition.rs @@ -38,7 +38,7 @@ impl WaitCondition { // Wait until notified. Unlocks guard when blocking is ready. Returns false if resumed by a signal or the notify_signal function pub fn wait(&self, guard: MutexGuard, reason: &'static str) -> bool { - let id; + let cid; { let context_lock = { let contexts = context::contexts(); @@ -53,7 +53,7 @@ impl WaitCondition { { return false; } - id = context.id; + cid = context.cid; context.block(reason); } @@ -73,7 +73,7 @@ impl WaitCondition { while i < contexts.len() { let remove = { let context = contexts[i].read(); - context.id == id + context.cid == cid }; if remove { diff --git a/src/syscall/fs.rs b/src/syscall/fs.rs index afad52ffae..a081d1eb6f 100644 --- a/src/syscall/fs.rs +++ b/src/syscall/fs.rs @@ -56,7 +56,7 @@ const PATH_MAX: usize = PAGE_SIZE; pub fn open(raw_path: UserSliceRo, flags: usize) -> Result { let (pid, uid, gid, scheme_ns, umask) = match context::current()?.read() { ref context => ( - context.id.into(), + context.pid.into(), context.euid, context.egid, context.ens, @@ -361,7 +361,7 @@ pub fn frename(fd: FileHandle, raw_path: UserSliceRo) -> Result<()> { CallerCtx { uid: context.euid, gid: context.egid, - pid: context.id.get(), + pid: context.pid.get(), }, context.ens, ), diff --git a/src/syscall/process.rs b/src/syscall/process.rs index ee87e262eb..fa126b931e 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -48,7 +48,7 @@ pub fn exit(status: usize) -> ! { .and_then(|a| Arc::try_unwrap(a).ok()); drop(context.syscall_head.take()); drop(context.syscall_tail.take()); - context.id + context.pid }; // Files must be closed while context is valid so that messages can be passed @@ -114,7 +114,7 @@ pub fn exit(status: usize) -> ! { } pub fn getpid() -> Result { - Ok(context::context_id()) + Ok(context::current()?.read().pid) } pub fn getpgid(pid: ContextId) -> Result { @@ -178,7 +178,7 @@ pub fn kill(pid: ContextId, sig: usize, parent_sigchld: bool) -> Result { } let mut send = |context: &mut context::Context| -> SendResult { - let is_self = context.id == context::context_id(); + let is_self = context.cid == context::current_cid(); // Non-root users cannot kill arbitrarily. if euid != 0 && euid != context.ruid && ruid != context.ruid { @@ -312,7 +312,7 @@ pub fn kill(pid: ContextId, sig: usize, parent_sigchld: bool) -> Result { for (pid, context_lock) in contexts.iter() { let mut context = context_lock.write(); - if context.id.get() <= 2 { + if context.pid.get() <= 2 { continue; } found += 1; @@ -373,7 +373,7 @@ pub fn setpgid(pid: ContextId, pgid: ContextId) -> Result { let current_pid = { let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - context.id + context.pid }; let context_lock = if pid.get() == 0 { @@ -383,9 +383,9 @@ pub fn setpgid(pid: ContextId, pgid: ContextId) -> Result { }; let mut context = context_lock.write(); - if context.id == current_pid || context.ppid == current_pid { + if context.pid == current_pid || context.ppid == current_pid { if pgid.get() == 0 { - context.pgid = context.id; + context.pgid = context.pid; } else { context.pgid = pgid; } @@ -439,7 +439,7 @@ pub fn waitpid( let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - (context.id, Arc::clone(&context.waitpid)) + (context.pid, Arc::clone(&context.waitpid)) }; let write_status = |value| { status_ptr @@ -543,7 +543,7 @@ pub fn waitpid( if context.ppid != ppid { println!( "TODO: Hack for rustc - changing ppid of {} from {} to {}", - context.id.get(), + context.pid.get(), context.ppid.get(), ppid.get() );