diff --git a/context/context.rs b/context/context.rs index 512c66e9a1ddaee382ad0628f6a855dc1e7a26f0..8c09573648973687b18b3e53a0ec44b67bb2dfa1 100644 --- a/context/context.rs +++ b/context/context.rs @@ -22,10 +22,14 @@ pub struct Context { pub id: usize, /// The ID of the parent context pub ppid: usize, - /// The user id - pub uid: u32, - /// The group id - pub gid: u32, + /// The real user id + pub ruid: u32, + /// The real group id + pub rgid: u32, + /// The effective user id + pub euid: u32, + /// The effective group id + pub egid: u32, /// Status of context pub status: Status, /// Context running or not @@ -62,8 +66,10 @@ impl Context { Context { id: id, ppid: 0, - uid: 0, - gid: 0, + ruid: 0, + rgid: 0, + euid: 0, + egid: 0, status: Status::Blocked, running: false, vfork: false, diff --git a/scheme/user.rs b/scheme/user.rs index 542f01e651127402bad5c37813d05c4efe8ecd52..6bc25fd41783d54ebea4841c3dce22fb8af0829c 100644 --- a/scheme/user.rs +++ b/scheme/user.rs @@ -38,7 +38,7 @@ impl UserInner { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - (context.id, context.uid, context.gid) + (context.id, context.euid, context.egid) }; let id = self.next_id.fetch_add(1, Ordering::SeqCst); diff --git a/syscall/fs.rs b/syscall/fs.rs index 1c969f6791d47736ba799ed56528f7e468379497..f527c36ced5e424724cb71f9c202b5ad5d563ff4 100644 --- a/syscall/fs.rs +++ b/syscall/fs.rs @@ -11,7 +11,7 @@ pub fn file_op(a: usize, fd: usize, c: usize, d: usize) -> Result<usize> { let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); let file = context.get_file(fd).ok_or(Error::new(EBADF))?; - (file, context.id, context.uid, context.gid) + (file, context.id, context.euid, context.egid) }; let scheme = { @@ -74,7 +74,7 @@ pub fn open(path: &[u8], flags: usize) -> Result<usize> { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - (context.canonicalize(path), context.uid, context.gid) + (context.canonicalize(path), context.euid, context.egid) }; let mut parts = path_canon.splitn(2, |&b| b == b':'); @@ -107,7 +107,7 @@ pub fn mkdir(path: &[u8], mode: u16) -> Result<usize> { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - (context.canonicalize(path), context.uid, context.gid) + (context.canonicalize(path), context.euid, context.egid) }; let mut parts = path_canon.splitn(2, |&b| b == b':'); @@ -129,7 +129,7 @@ pub fn rmdir(path: &[u8]) -> Result<usize> { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - (context.canonicalize(path), context.uid, context.gid) + (context.canonicalize(path), context.euid, context.egid) }; let mut parts = path_canon.splitn(2, |&b| b == b':'); @@ -151,7 +151,7 @@ pub fn unlink(path: &[u8]) -> Result<usize> { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - (context.canonicalize(path), context.uid, context.gid) + (context.canonicalize(path), context.euid, context.egid) }; let mut parts = path_canon.splitn(2, |&b| b == b':'); diff --git a/syscall/mod.rs b/syscall/mod.rs index c0d389ef93b10f92d3c44eebe405c49784d26f87..fc357a6b5781f11839a01f2b128c07b5c27ecda8 100644 --- a/syscall/mod.rs +++ b/syscall/mod.rs @@ -55,6 +55,8 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize SYS_GETCWD => getcwd(validate_slice_mut(b as *mut u8, c)?), SYS_GETUID => getuid(), SYS_GETGID => getgid(), + SYS_GETEUID => geteuid(), + SYS_GETEGID => getegid(), SYS_SETUID => setuid(b as u32), SYS_SETGID => setgid(b as u32), SYS_PHYSALLOC => physalloc(b), diff --git a/syscall/process.rs b/syscall/process.rs index 9519ef2bff1aab7c40de05f61196243d9e4190fa..e00d3146e9e47b15bc64c9d8719d1c6553cecf42 100644 --- a/syscall/process.rs +++ b/syscall/process.rs @@ -1,7 +1,7 @@ ///! Process syscalls use alloc::arc::Arc; use alloc::boxed::Box; -use collections::Vec; +use collections::{BTreeMap, Vec}; use core::mem; use core::str; use spin::Mutex; @@ -58,8 +58,10 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { let ppid; let pid; { - let uid; - let gid; + let ruid; + let rgid; + let euid; + let egid; let arch; let vfork; let mut kfx_option = None; @@ -80,8 +82,10 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { let context = context_lock.read(); ppid = context.id; - uid = context.uid; - gid = context.gid; + ruid = context.ruid; + rgid = context.rgid; + euid = context.euid; + egid = context.egid; arch = context.arch.clone(); @@ -191,7 +195,11 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { if flags & CLONE_VM == CLONE_VM { env = context.env.clone(); } else { - env = Arc::new(Mutex::new(context.env.lock().clone())); + let mut new_env = BTreeMap::new(); + for item in context.env.lock().iter() { + new_env.insert(item.0.clone(), Arc::new(Mutex::new(item.1.lock().clone()))); + } + env = Arc::new(Mutex::new(new_env)); } if flags & CLONE_FILES == CLONE_FILES { @@ -253,8 +261,10 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> { pid = context.id; context.ppid = ppid; - context.uid = uid; - context.gid = gid; + context.ruid = ruid; + context.rgid = rgid; + context.euid = euid; + context.egid = egid; context.status = context::Status::Runnable; @@ -436,7 +446,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - (context.uid, context.gid) + (context.euid, context.egid) }; let file = syscall::open(path, 0)?; @@ -483,11 +493,11 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> { context.grants = Arc::new(Mutex::new(Vec::new())); if stat.st_mode & syscall::flag::MODE_SETUID == syscall::flag::MODE_SETUID { - context.uid = stat.st_uid; + context.euid = stat.st_uid; } if stat.st_mode & syscall::flag::MODE_SETGID == syscall::flag::MODE_SETGID { - context.gid = stat.st_gid; + context.egid = stat.st_gid; } // Map and copy new segments @@ -612,11 +622,25 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> { unsafe { usermode(entry, sp); } } +pub fn getegid() -> Result<usize> { + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + Ok(context.egid as usize) +} + +pub fn geteuid() -> Result<usize> { + let contexts = context::contexts(); + let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; + let context = context_lock.read(); + Ok(context.euid as usize) +} + pub fn getgid() -> Result<usize> { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - Ok(context.gid as usize) + Ok(context.rgid as usize) } pub fn getpid() -> Result<usize> { @@ -630,7 +654,7 @@ pub fn getuid() -> Result<usize> { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let context = context_lock.read(); - Ok(context.uid as usize) + Ok(context.ruid as usize) } pub fn iopl(_level: usize) -> Result<usize> { @@ -734,10 +758,9 @@ pub fn setgid(gid: u32) -> Result<usize> { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let mut context = context_lock.write(); - if context.gid == 0 { - context.gid = gid; - Ok(0) - } else if context.gid == gid { + if context.egid == 0 { + context.rgid = gid; + context.egid = gid; Ok(0) } else { Err(Error::new(EPERM)) @@ -748,10 +771,9 @@ pub fn setuid(uid: u32) -> Result<usize> { let contexts = context::contexts(); let context_lock = contexts.current().ok_or(Error::new(ESRCH))?; let mut context = context_lock.write(); - if context.uid == 0 { - context.uid = uid; - Ok(0) - } else if context.uid == uid { + if context.euid == 0 { + context.ruid = uid; + context.euid = uid; Ok(0) } else { Err(Error::new(EPERM))