Implement a capability namespace with no available schemes

This commit is contained in:
Jeremy Soller
2017-10-09 20:12:08 -06:00
parent b023a715f9
commit 244069cf43
2 changed files with 146 additions and 55 deletions

View File

@@ -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();

View File

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