diff --git a/scheme/sys/context.rs b/scheme/sys/context.rs index a67b62dc1f35629898ce3fc9fffa440eaefe7048..26e3e2d66182bd7e1d0c7e1b683ddfb0f60d191a 100644 --- a/scheme/sys/context.rs +++ b/scheme/sys/context.rs @@ -5,11 +5,13 @@ use context; use syscall::error::Result; pub fn resource() -> Result<Vec<u8>> { - let mut string = format!("{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<8}{:<6}{}\n", + let mut string = format!("{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<8}{:<6}{}\n", "PID", "PPID", - "UID", - "GID", + "RUID", + "RGID", + "EUID", + "EGID", "STAT", "CPU", "MEM", @@ -83,9 +85,11 @@ pub fn resource() -> Result<Vec<u8>> { let name_bytes = context.name.lock(); let name = str::from_utf8(&name_bytes).unwrap_or(""); - string.push_str(&format!("{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<8}{:<6}{}\n", + string.push_str(&format!("{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<6}{:<8}{:<6}{}\n", context.id.into(), context.ppid.into(), + context.ruid, + context.rgid, context.euid, context.egid, stat_string, diff --git a/syscall/mod.rs b/syscall/mod.rs index 0bb1a64ac2d93d5838cd938f0b0ff6d56c2c89ae..c4e30aef1dc5cf3567fb4dcf8ccfa5c45a36e07b 100644 --- a/syscall/mod.rs +++ b/syscall/mod.rs @@ -86,8 +86,8 @@ pub extern fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize SYS_GETGID => getgid(), SYS_GETEUID => geteuid(), SYS_GETEGID => getegid(), - SYS_SETUID => setuid(b as u32), - SYS_SETGID => setgid(b as u32), + SYS_SETREUID => setreuid(b as u32, c as u32), + SYS_SETREGID => setregid(b as u32, c as u32), SYS_SETNS => setns(validate_slice(b as *const [usize; 2], c)?), SYS_PIPE2 => pipe2(validate_slice_mut(b as *mut usize, 2)?, c), SYS_PHYSALLOC => physalloc(b), diff --git a/syscall/privilege.rs b/syscall/privilege.rs index a4ce3368f481a257f4e9f272bb15aedca91f8ba7..e1abd8a271b92c88a4f0a0ecf7c0daf6e03d09f6 100644 --- a/syscall/privilege.rs +++ b/syscall/privilege.rs @@ -33,26 +33,52 @@ pub fn getuid() -> Result<usize> { Ok(context.ruid as usize) } -pub fn setgid(gid: u32) -> Result<usize> { +pub fn setregid(rgid: u32, egid: 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.egid == 0 { - context.rgid = gid; - context.egid = gid; + + if (context.euid == 0 + || rgid as i32 == -1 + || rgid == context.egid + || rgid == context.rgid) + && (context.euid == 0 + || egid as i32 == -1 + || egid == context.egid + || egid == context.rgid) + { + if rgid as i32 != -1 { + context.rgid = rgid; + } + if egid as i32 != -1 { + context.egid = egid; + } Ok(0) } else { Err(Error::new(EPERM)) } } -pub fn setuid(uid: u32) -> Result<usize> { +pub fn setreuid(ruid: u32, euid: 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.euid == 0 { - context.ruid = uid; - context.euid = uid; + + if (context.euid == 0 + || ruid as i32 == -1 + || ruid == context.euid + || ruid == context.ruid) + && (context.euid == 0 + || euid as i32 == -1 + || euid == context.euid + || euid == context.ruid) + { + if ruid as i32 != -1 { + context.ruid = ruid; + } + if euid as i32 != -1 { + context.euid = euid; + } Ok(0) } else { Err(Error::new(EPERM))