Merge pull request #57 from redox-os/cap
Capability mode support using null namespace
This commit is contained in:
@@ -41,7 +41,7 @@ use alloc::arc::Arc;
|
||||
use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering};
|
||||
use spin::Mutex;
|
||||
|
||||
use scheme::FileHandle;
|
||||
use scheme::{FileHandle, SchemeNamespace};
|
||||
|
||||
pub use consts::*;
|
||||
|
||||
@@ -146,6 +146,8 @@ pub fn kmain(cpus: usize, env: &[u8]) -> ! {
|
||||
match context::contexts_mut().spawn(userspace_init) {
|
||||
Ok(context_lock) => {
|
||||
let mut context = context_lock.write();
|
||||
context.rns = SchemeNamespace::from(1);
|
||||
context.ens = SchemeNamespace::from(1);
|
||||
context.status = context::Status::Runnable;
|
||||
|
||||
let mut context_env = context.env.lock();
|
||||
|
||||
@@ -99,7 +99,8 @@ impl SchemeList {
|
||||
let mut list = SchemeList {
|
||||
map: BTreeMap::new(),
|
||||
names: BTreeMap::new(),
|
||||
next_ns: 0,
|
||||
// Scheme namespaces always start at 1. 0 is a reserved namespace, the null namespace
|
||||
next_ns: 1,
|
||||
next_id: 1
|
||||
};
|
||||
list.new_root();
|
||||
|
||||
@@ -73,25 +73,51 @@ pub fn setregid(rgid: u32, egid: u32) -> Result<usize> {
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let mut context = context_lock.write();
|
||||
|
||||
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))
|
||||
let setrgid =
|
||||
if context.euid == 0 {
|
||||
// Allow changing RGID if root
|
||||
true
|
||||
} else if rgid == context.egid {
|
||||
/// Allow changing RGID if used for EGID
|
||||
true
|
||||
} else if rgid == context.rgid {
|
||||
/// Allow changing RGID if used for RGID
|
||||
true
|
||||
} else if rgid as i32 == -1 {
|
||||
// Ignore RGID if -1 is passed
|
||||
false
|
||||
} else {
|
||||
// Not permitted otherwise
|
||||
return Err(Error::new(EPERM));
|
||||
};
|
||||
|
||||
let setegid =
|
||||
if context.euid == 0 {
|
||||
// Allow changing EGID if root
|
||||
true
|
||||
} else if egid == context.egid {
|
||||
/// Allow changing EGID if used for EGID
|
||||
true
|
||||
} else if egid == context.rgid {
|
||||
/// Allow changing EGID if used for RGID
|
||||
true
|
||||
} else if egid as i32 == -1 {
|
||||
// Ignore EGID if -1 is passed
|
||||
false
|
||||
} else {
|
||||
// Not permitted otherwise
|
||||
return Err(Error::new(EPERM));
|
||||
};
|
||||
|
||||
if setrgid {
|
||||
context.rgid = rgid;
|
||||
}
|
||||
|
||||
if setegid {
|
||||
context.egid = egid;
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn setrens(rns: SchemeNamespace, ens: SchemeNamespace) -> Result<usize> {
|
||||
@@ -99,25 +125,63 @@ pub fn setrens(rns: SchemeNamespace, ens: SchemeNamespace) -> Result<usize> {
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let mut context = context_lock.write();
|
||||
|
||||
if (context.euid == 0
|
||||
|| rns.into() as isize == -1
|
||||
|| rns == context.ens
|
||||
|| rns == context.rns)
|
||||
&& (context.euid == 0
|
||||
|| ens.into() as isize == -1
|
||||
|| ens == context.ens
|
||||
|| ens == context.rns)
|
||||
{
|
||||
if rns.into() as isize != -1 {
|
||||
context.rns = rns;
|
||||
}
|
||||
if ens.into() as isize != -1 {
|
||||
context.ens = ens;
|
||||
}
|
||||
Ok(0)
|
||||
} else {
|
||||
Err(Error::new(EPERM))
|
||||
let setrns =
|
||||
if rns.into() == 0 {
|
||||
// Allow entering capability mode
|
||||
true
|
||||
} else if context.rns.into() == 0 {
|
||||
// Do not allow leaving capability mode
|
||||
return Err(Error::new(EPERM));
|
||||
} else if context.euid == 0 {
|
||||
// Allow setting RNS if root
|
||||
true
|
||||
} else if rns == context.ens {
|
||||
// Allow setting RNS if used for ENS
|
||||
true
|
||||
} else if rns == context.rns {
|
||||
// Allow setting RNS if used for RNS
|
||||
true
|
||||
} else if rns.into() as isize == -1 {
|
||||
// Ignore RNS if -1 is passed
|
||||
false
|
||||
} else {
|
||||
// Not permitted otherwise
|
||||
return Err(Error::new(EPERM));
|
||||
};
|
||||
|
||||
let setens =
|
||||
if ens.into() == 0 {
|
||||
// Allow entering capability mode
|
||||
true
|
||||
} else if context.ens.into() == 0 {
|
||||
// Do not allow leaving capability mode
|
||||
return Err(Error::new(EPERM));
|
||||
} else if context.euid == 0 {
|
||||
// Allow setting ENS if root
|
||||
true
|
||||
} else if ens == context.ens {
|
||||
// Allow setting ENS if used for ENS
|
||||
true
|
||||
} else if ens == context.rns {
|
||||
// Allow setting ENS if used for RNS
|
||||
true
|
||||
} else if ens.into() as isize == -1 {
|
||||
// Ignore ENS if -1 is passed
|
||||
false
|
||||
} else {
|
||||
// Not permitted otherwise
|
||||
return Err(Error::new(EPERM));
|
||||
};
|
||||
|
||||
if setrns {
|
||||
context.rns = rns;
|
||||
}
|
||||
|
||||
if setens {
|
||||
context.ens = ens;
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
pub fn setreuid(ruid: u32, euid: u32) -> Result<usize> {
|
||||
@@ -125,23 +189,49 @@ pub fn setreuid(ruid: u32, euid: u32) -> Result<usize> {
|
||||
let context_lock = contexts.current().ok_or(Error::new(ESRCH))?;
|
||||
let mut context = context_lock.write();
|
||||
|
||||
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))
|
||||
let setruid =
|
||||
if context.euid == 0 {
|
||||
// Allow setting RUID if root
|
||||
true
|
||||
} else if ruid == context.euid {
|
||||
// Allow setting RUID if used for EUID
|
||||
true
|
||||
} else if ruid == context.ruid {
|
||||
// Allow setting RUID if used for RUID
|
||||
true
|
||||
} else if ruid as i32 == -1 {
|
||||
// Ignore RUID if -1 is passed
|
||||
false
|
||||
} else {
|
||||
// Not permitted otherwise
|
||||
return Err(Error::new(EPERM));
|
||||
};
|
||||
|
||||
let seteuid =
|
||||
if context.euid == 0 {
|
||||
// Allow setting EUID if root
|
||||
true
|
||||
} else if euid == context.euid {
|
||||
// Allow setting EUID if used for EUID
|
||||
true
|
||||
} else if euid == context.ruid {
|
||||
// Allow setting EUID if used for RUID
|
||||
true
|
||||
} else if euid as i32 == -1 {
|
||||
// Ignore EUID if -1 is passed
|
||||
false
|
||||
} else {
|
||||
// Not permitted otherwise
|
||||
return Err(Error::new(EPERM));
|
||||
};
|
||||
|
||||
if setruid {
|
||||
context.ruid = ruid;
|
||||
}
|
||||
|
||||
if seteuid {
|
||||
context.euid = euid;
|
||||
}
|
||||
|
||||
Ok(0)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user