vmm: Support setting seccomp to errno

This will generate -EPERM on seccomp violations as opposed to causing
the VMM to exit with SIGSYS.

Signed-off-by: Rob Bradford <rbradford@meta.com>
This commit is contained in:
Rob Bradford
2026-06-05 10:56:17 +01:00
committed by Bo Chen
parent 9c5180fc2c
commit 58306b6f28
4 changed files with 20 additions and 22 deletions

View File

@@ -454,7 +454,7 @@ fn get_cli_options_sorted(
Arg::new("seccomp")
.long("seccomp")
.num_args(1)
.value_parser(["true", "false", "log"])
.value_parser(["true", "false", "log", "errno"])
.default_value("true"),
Arg::new("serial")
.long("serial")
@@ -588,6 +588,7 @@ fn start_vmm(
"true" => SeccompAction::Trap,
"false" => SeccompAction::Allow,
"log" => SeccompAction::Log,
"errno" => SeccompAction::Errno(libc::EPERM as u32),
val => {
// The user providing an invalid value will be rejected
panic!("Invalid parameter {val} for \"--seccomp\" flag");

View File

@@ -57,6 +57,22 @@ $ ausyscall 47
recvmsg
```
### Returning EPERM instead of killing the VMM
Append `--seccomp errno` to make prohibited system calls return `EPERM` to the
caller instead of terminating the process. This lets the VMM keep running so a
regression caused by an unknown syscall can be observed without an immediate
crash, at the cost of turning the violation into a soft failure visible only as
a syscall error.
By default the kernel does not log `errno` actions. To audit them, ensure
`errno` is included in the host's `kernel.seccomp.actions_logged` sysctl, for
example:
```
# sysctl -w kernel.seccomp.actions_logged='kill_process kill_thread trap errno log'
```
### Further debug with `strace`
One more way of debugging seccomp related issues is to use the `strace` tool as

View File

@@ -380,17 +380,9 @@ pub fn get_seccomp_filter(
) -> Result<BpfProgram, Error> {
match seccomp_action {
SeccompAction::Allow => Ok(vec![]),
SeccompAction::Log => SeccompFilter::new(
get_seccomp_rules(thread_type).into_iter().collect(),
SeccompAction::Log,
SeccompAction::Allow,
env::consts::ARCH.try_into().unwrap(),
)
.and_then(|filter| filter.try_into())
.map_err(Error::Backend),
_ => SeccompFilter::new(
get_seccomp_rules(thread_type).into_iter().collect(),
SeccompAction::Trap,
seccomp_action.clone(),
SeccompAction::Allow,
env::consts::ARCH.try_into().unwrap(),
)

View File

@@ -1249,23 +1249,12 @@ pub fn get_seccomp_filter(
) -> Result<BpfProgram, Error> {
match seccomp_action {
SeccompAction::Allow => Ok(vec![]),
SeccompAction::Log => SeccompFilter::new(
get_seccomp_rules(thread_type, hypervisor_type)
.map_err(Error::Backend)?
.into_iter()
.collect(),
SeccompAction::Log,
SeccompAction::Allow,
consts::ARCH.try_into().unwrap(),
)
.and_then(|filter| filter.try_into())
.map_err(Error::Backend),
_ => SeccompFilter::new(
get_seccomp_rules(thread_type, hypervisor_type)
.map_err(Error::Backend)?
.into_iter()
.collect(),
SeccompAction::Trap,
seccomp_action.clone(),
SeccompAction::Allow,
consts::ARCH.try_into().unwrap(),
)