Skip to content

Commit

Permalink
seccomp: Restrict rlimit to get-self
Browse files Browse the repository at this point in the history
  • Loading branch information
mbuesch committed Jan 24, 2025
1 parent 41a8f7b commit 6706fac
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 25 deletions.
89 changes: 65 additions & 24 deletions letmein-seccomp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@ use anyhow::{self as ah, Context as _};
use seccompiler::{apply_filter_all_threads, BpfProgram};
use std::env::consts::ARCH;

#[cfg(has_seccomp_support)]
const NULL: u64 = 0;
#[cfg(has_seccomp_support)]
const PTR: u8 = 0xFF;

#[cfg(has_seccomp_support)]
macro_rules! sys {
($ident:ident) => {{
Expand All @@ -24,18 +29,42 @@ macro_rules! sys {
}};
}

#[cfg(has_seccomp_support)]
fn seccomp_cond(idx: u8, value: u64, bit_width: u8) -> ah::Result<seccompiler::SeccompCondition> {
use seccompiler::{SeccompCmpArgLen, SeccompCmpOp, SeccompCondition};

let bit_width = match bit_width {
PTR => {
#[cfg(target_pointer_width = "32")]
let bit_width = 32;

#[cfg(target_pointer_width = "64")]
let bit_width = 64;

bit_width
}
bit_width => bit_width,
};

let arglen = match bit_width {
32 => {
assert_eq!(value & 0xFFFF_FFFF_0000_0000, 0);
SeccompCmpArgLen::Dword
}
64 => SeccompCmpArgLen::Qword,
_ => unreachable!(),
};

Ok(SeccompCondition::new(idx, arglen, SeccompCmpOp::Eq, value)?)
}

#[cfg(has_seccomp_support)]
macro_rules! args {
($($arg:literal == $value:expr),*) => {
($([ $arg:literal ] ($bit_width:expr) == $value:expr),*) => {
SeccompRule::new(
vec![
$(
SeccompCondition::new(
$arg,
SeccompCmpArgLen::Dword,
SeccompCmpOp::Eq,
($value) as _,
)?,
seccomp_cond($arg, ($value) as _, $bit_width)?,
)*
]
)?
Expand Down Expand Up @@ -80,7 +109,7 @@ pub enum Allow {
Clone,
Exec,
Wait,
Rlimit,
GetRlimit,
Uname,
Pidfd,
}
Expand All @@ -106,10 +135,7 @@ impl Filter {
pub fn compile_for_arch(allow: &[Allow], deny_action: Action, arch: &str) -> ah::Result<Self> {
assert!(!allow.is_empty());

use seccompiler::{
SeccompAction, SeccompCmpArgLen, SeccompCmpOp, SeccompCondition, SeccompFilter,
SeccompRule,
};
use seccompiler::{SeccompAction, SeccompFilter, SeccompRule};
use std::collections::BTreeMap;

type RulesMap = BTreeMap<i64, Vec<SeccompRule>>;
Expand Down Expand Up @@ -197,41 +223,53 @@ impl Filter {
}
Allow::UnixAccept => {
add_sys(&mut map, sys!(SYS_accept4));
add_sys_args_match(&mut map, sys!(SYS_socket), args!(0 == libc::AF_UNIX));
add_sys_args_match(&mut map, sys!(SYS_socket), args!([0](32) == libc::AF_UNIX));
add_sys(&mut map, sys!(SYS_getsockopt));
add_sys(&mut map, sys!(SYS_getpeername));
}
Allow::UnixConnect => {
add_sys(&mut map, sys!(SYS_connect));
add_sys_args_match(&mut map, sys!(SYS_socket), args!(0 == libc::AF_UNIX));
add_sys_args_match(&mut map, sys!(SYS_socket), args!([0](32) == libc::AF_UNIX));
add_sys(&mut map, sys!(SYS_getsockopt));
add_sys(&mut map, sys!(SYS_getpeername));
}
Allow::TcpAccept => {
add_sys(&mut map, sys!(SYS_accept4));
add_sys_args_match(&mut map, sys!(SYS_socket), args!(0 == libc::AF_INET));
add_sys_args_match(&mut map, sys!(SYS_socket), args!(0 == libc::AF_INET6));
add_sys_args_match(&mut map, sys!(SYS_socket), args!([0](32) == libc::AF_INET));
add_sys_args_match(
&mut map,
sys!(SYS_socket),
args!([0](32) == libc::AF_INET6),
);
add_sys(&mut map, sys!(SYS_getsockopt));
add_sys(&mut map, sys!(SYS_getpeername));
}
Allow::TcpConnect => {
add_sys(&mut map, sys!(SYS_connect));
add_sys_args_match(&mut map, sys!(SYS_socket), args!(0 == libc::AF_INET));
add_sys_args_match(&mut map, sys!(SYS_socket), args!(0 == libc::AF_INET6));
add_sys_args_match(&mut map, sys!(SYS_socket), args!([0](32) == libc::AF_INET));
add_sys_args_match(
&mut map,
sys!(SYS_socket),
args!([0](32) == libc::AF_INET6),
);
add_sys(&mut map, sys!(SYS_getsockopt));
add_sys(&mut map, sys!(SYS_getpeername));
}
Allow::Netlink => {
add_sys(&mut map, sys!(SYS_connect));
add_sys_args_match(&mut map, sys!(SYS_socket), args!(0 == libc::AF_NETLINK));
add_sys_args_match(
&mut map,
sys!(SYS_socket),
args!([0](32) == libc::AF_NETLINK),
);
add_sys(&mut map, sys!(SYS_getsockopt));
}
Allow::SetSockOpt { level_optname } => {
if let Some((level, optname)) = level_optname {
add_sys_args_match(
&mut map,
sys!(SYS_setsockopt),
args!(1 == level, 2 == optname),
args!([1](32) == level, [2](32) == optname),
);
} else {
add_sys(&mut map, sys!(SYS_setsockopt));
Expand Down Expand Up @@ -272,7 +310,7 @@ impl Filter {
}
Allow::Fcntl { op } => match op {
Some(op) => {
add_sys_args_match(&mut map, sys!(SYS_fcntl), args!(1 == op));
add_sys_args_match(&mut map, sys!(SYS_fcntl), args!([1](32) == op));
}
None => {
add_sys(&mut map, sys!(SYS_fcntl));
Expand Down Expand Up @@ -330,9 +368,12 @@ impl Filter {
Allow::Wait => {
add_sys(&mut map, sys!(SYS_wait4));
}
Allow::Rlimit => {
//TODO do we only need `get`?
add_sys(&mut map, sys!(SYS_prlimit64));
Allow::GetRlimit => {
add_sys_args_match(
&mut map,
sys!(SYS_prlimit64),
args!([0](32) == 0, [2](PTR) == NULL),
);
}
Allow::Uname => {
add_sys(&mut map, sys!(SYS_uname));
Expand Down
2 changes: 1 addition & 1 deletion letmeinfwd/src/seccomp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const ALLOW_LIST: [Allow; 29] = [
Allow::Clone,
Allow::Exec,
Allow::Wait,
Allow::Rlimit,
Allow::GetRlimit,
Allow::Pidfd,
];

Expand Down

0 comments on commit 6706fac

Please sign in to comment.