seccompiler
seccompiler copied to clipboard
Use of BTreeMap can cause inadvertant loss of syscall rules when syscalls duplicated
In the case where the SeccompFilter rules are generated from a list of (syscall, Vec<SeccompRule)
(as in the doc examples), if a syscall is repeated with different args, the later rule will silently overwrite the earlier one. This is a limitation of the Vec->BTreeMap collect
implemenation. Given that rules
is converted into an iterator over (syscall, Vec<SeccompRule)
during try_from the use of a map doesn't seem to add anything.
This has implications for ease-of-use of the library. I came across this issue when implementing a port of OpenBSD pledge(). In pledge()
semantics, promises are additive; cpath
adds the ability to call open()
with O_CREAT
, and wpath
allows open()
with O_WRONLY
; to open and then write a file you would need to specify both.
The simplest way to implement this is a separate whitelist for each case, and then chain them together as needed, e.g:
let cpath = vec![(
libc::SYS_open,
vec![
Rule::new(vec![
Cond::new(
1,
ArgLen::Dword,
CmpOp::MaskedEq(libc::O_CREAT as u64),
libc::O_CREAT as u64,
)?])?,
])];
let wpath = vec![(
libc::SYS_open,
vec![
Rule::new(vec![Cond::new(
1,
ArgLen::Dword,
CmpOp::MaskedEq(libc::O_ACCMODE as u64),
libc::O_WRONLY as u64,
)?])?,
],
)];
// This list would actually be based on caller parameters
let rules: Vec<(i64, Vec<Rule>)> = cpath.into_iter()
.chain(wpath)
.collect();
let sf = SeccompFilter::new(
rules.into_iter().collect(),
Action::KillProcess,
Action::Allow,
ARCH.try_into()?,
)?;
However the use of BTreeMap means the cpath
rule would be completely overwritten by the wpath
rule, and attempts to create the file would fail.
The simplest solution would be to use a Vec for the syscall rule list (i.e. just skip the BTreeMap conversion) and leave the partitioning of the syscall rules up the caller. I've already tried this with v0.3.0 and it works fine; I'm happy to raise a PR. However it would obviously be a breaking change for current users of the lib.