Separate context and process IDs.

This commit is contained in:
4lDO2
2024-07-08 14:10:31 +02:00
parent 74b824f40f
commit 0da2fce64a
14 changed files with 63 additions and 56 deletions
+1 -1
View File
@@ -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);
}
+10 -7
View File
@@ -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<Context> {
pub fn new(cid: ContextId, pid: ContextId) -> Result<Context> {
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,
}
+3 -2
View File
@@ -50,7 +50,7 @@ impl ContextList {
/// Get the current context.
pub fn current(&self) -> Option<&Arc<RwSpinlock<Context>>> {
self.map.get(&super::context_id())
self.map.get(&super::current_cid())
}
pub fn iter(
@@ -72,7 +72,8 @@ impl ContextList {
) -> Result<&Arc<RwSpinlock<Context>>> {
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
+4 -4
View File
@@ -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<Arc<RwSpinlock<Context>>> {
+10 -10
View File
@@ -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<Option<SwitchResultInner>>,
pit_ticks: Cell<usize>,
/// Unique ID of the currently running context.
context_id: Cell<ContextId>,
/// Unique context ID of the currently running context.
current_cid: Cell<ContextId>,
// The ID of the idle process
idle_id: Cell<ContextId>,
@@ -260,11 +260,11 @@ pub struct ContextSwitchPercpu {
pub(crate) being_sigkilled: Cell<bool>,
}
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()
+1 -1
View File
@@ -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();
+1 -1
View File
@@ -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
{
+2 -2
View File
@@ -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<PtraceFlags> {
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?;
+14 -11
View File
@@ -75,7 +75,7 @@ fn try_stop_context<F, T>(pid: ContextId, callback: F) -> Result<T>
where
F: FnOnce(&mut Context) -> Result<T>,
{
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<const FULL: bool> ProcScheme<FULL> {
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<const FULL: bool> ProcScheme<FULL> {
// 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<const FULL: bool> ProcScheme<FULL> {
flags,
pid,
operation: operation.clone(),
cid: pid,
},
data,
},
@@ -471,7 +473,7 @@ impl<const FULL: bool> ProcScheme<FULL> {
#[cfg(target_arch = "x86_64")]
fn read_env_regs(&self, info: &Info) -> Result<EnvRegisters> {
// 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<const FULL: bool> ProcScheme<FULL> {
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<const FULL: bool> KernelScheme for ProcScheme<FULL> {
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<const FULL: bool> KernelScheme for ProcScheme<FULL> {
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<const FULL: bool> KernelScheme for ProcScheme<FULL> {
info: Info {
flags: 0,
pid: info.pid,
cid: info.cid,
operation,
},
data,
@@ -1578,12 +1581,12 @@ fn inherit_context() -> Result<ContextId> {
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!(
+1 -1
View File
@@ -106,7 +106,7 @@ pub fn resource() -> Result<Vec<u8>> {
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(),
+2 -2
View File
@@ -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(
+3 -3
View File
@@ -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<T>(&self, guard: MutexGuard<T>, 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 {
+2 -2
View File
@@ -56,7 +56,7 @@ const PATH_MAX: usize = PAGE_SIZE;
pub fn open(raw_path: UserSliceRo, flags: usize) -> Result<FileHandle> {
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,
),
+9 -9
View File
@@ -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<ContextId> {
Ok(context::context_id())
Ok(context::current()?.read().pid)
}
pub fn getpgid(pid: ContextId) -> Result<ContextId> {
@@ -178,7 +178,7 @@ pub fn kill(pid: ContextId, sig: usize, parent_sigchld: bool) -> Result<usize> {
}
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<usize> {
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<usize> {
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<usize> {
};
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()
);