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))