From df87992af4b7b5d0b11e478502e90005bef77fca Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Wed, 5 Oct 2016 20:31:59 -0600 Subject: [PATCH] Add sudo command, add effective UID and GID, and groups file --- context/context.rs | 18 ++++++++----- scheme/user.rs | 2 +- syscall/fs.rs | 10 ++++---- syscall/mod.rs | 2 ++ syscall/process.rs | 64 +++++++++++++++++++++++++++++++--------------- 5 files changed, 63 insertions(+), 33 deletions(-) diff --git a/context/context.rs b/context/context.rs index 512c66e9..8c095736 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 542f01e6..6bc25fd4 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 1c969f67..f527c36c 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 c0d389ef..fc357a6b 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 9519ef2b..e00d3146 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)) -- GitLab