seccomp: avoid hardcoding ioctl numbers

These can differ between platforms, so it's better to use centralized
definitions of them.  We can't currently do this for the KVM and VFIO
ioctls, because the corresponding crates don't publicly expose the
ioctl numbers.

Signed-off-by: Alyssa Ross <hi@alyssa.is>
This commit is contained in:
Alyssa Ross 2025-09-09 15:52:40 +02:00 committed by Rob Bradford
parent 305bec056f
commit 093f62858f
4 changed files with 100 additions and 126 deletions

1
Cargo.lock generated
View file

@ -2489,6 +2489,7 @@ dependencies = [
"uuid",
"vfio-ioctls",
"vfio_user",
"vhost",
"virtio-bindings",
"virtio-devices",
"vm-allocator",

View file

@ -4,6 +4,7 @@
//
// SPDX-License-Identifier: Apache-2.0
use libc::{FIONBIO, TIOCGWINSZ, TUNSETOFFLOAD};
use seccompiler::SeccompCmpOp::Eq;
use seccompiler::{
BpfProgram, Error, SeccompAction, SeccompCmpArgLen as ArgLen, SeccompCondition as Cond,
@ -46,17 +47,10 @@ macro_rules! or {
($($x:expr),*) => (vec![$($x),*])
}
// See include/uapi/asm-generic/ioctls.h in the kernel code.
const TIOCGWINSZ: u64 = 0x5413;
const FIONBIO: u64 = 0x5421;
// See include/uapi/linux/vfio.h in the kernel code.
const VFIO_IOMMU_MAP_DMA: u64 = 0x3b71;
const VFIO_IOMMU_UNMAP_DMA: u64 = 0x3b72;
// See include/uapi/linux/if_tun.h in the kernel code.
const TUNSETOFFLOAD: u64 = 0x4004_54d0;
#[cfg(feature = "sev_snp")]
fn mshv_sev_snp_ioctl_seccomp_rule() -> SeccompRule {
and![Cond::new(
@ -75,7 +69,7 @@ fn create_mshv_sev_snp_ioctl_seccomp_rule() -> Vec<SeccompRule> {
fn create_virtio_console_ioctl_seccomp_rule() -> Vec<SeccompRule> {
or![
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGWINSZ).unwrap()],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGWINSZ as _).unwrap()],
#[cfg(feature = "sev_snp")]
mshv_sev_snp_ioctl_seccomp_rule(),
]
@ -157,7 +151,7 @@ fn virtio_net_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
fn create_virtio_net_ctl_ioctl_seccomp_rule() -> Vec<SeccompRule> {
or![
and![Cond::new(1, ArgLen::Dword, Eq, TUNSETOFFLOAD).unwrap()],
and![Cond::new(1, ArgLen::Dword, Eq, TUNSETOFFLOAD as _).unwrap()],
#[cfg(feature = "sev_snp")]
mshv_sev_snp_ioctl_seccomp_rule(),
]
@ -231,7 +225,7 @@ fn virtio_vhost_block_thread_rules() -> Vec<(i64, Vec<SeccompRule>)> {
fn create_vsock_ioctl_seccomp_rule() -> Vec<SeccompRule> {
or![
and![Cond::new(1, ArgLen::Dword, Eq, FIONBIO,).unwrap()],
and![Cond::new(1, ArgLen::Dword, Eq, FIONBIO as _).unwrap()],
#[cfg(feature = "sev_snp")]
mshv_sev_snp_ioctl_seccomp_rule(),
]

View file

@ -78,6 +78,7 @@ tracer = { path = "../tracer" }
uuid = { workspace = true }
vfio-ioctls = { workspace = true, default-features = false }
vfio_user = { workspace = true }
vhost = { workspace = true }
virtio-bindings = { workspace = true }
virtio-devices = { path = "../virtio-devices" }
vm-allocator = { path = "../vm-allocator" }

View file

@ -5,11 +5,25 @@
// SPDX-License-Identifier: Apache-2.0
use hypervisor::HypervisorType;
use libc::{
BLKIOMIN, BLKIOOPT, BLKPBSZGET, BLKSSZGET, FIOCLEX, FIONBIO, SIOCGIFFLAGS, SIOCGIFHWADDR,
SIOCGIFINDEX, SIOCGIFMTU, SIOCSIFADDR, SIOCSIFFLAGS, SIOCSIFHWADDR, SIOCSIFMTU, SIOCSIFNETMASK,
TCGETS, TCGETS2, TCSETS, TCSETS2, TIOCGPGRP, TIOCGPTPEER, TIOCGWINSZ, TIOCSCTTY, TIOCSPGRP,
TIOCSPTLCK, TUNGETFEATURES, TUNGETIFF, TUNSETIFF, TUNSETOFFLOAD, TUNSETVNETHDRSZ,
};
use seccompiler::SeccompCmpOp::Eq;
use seccompiler::{
BackendError, BpfProgram, Error, SeccompAction, SeccompCmpArgLen as ArgLen,
SeccompCondition as Cond, SeccompFilter, SeccompRule,
};
use vhost::vhost_kern::vhost_binding::{
VHOST_GET_BACKEND_FEATURES, VHOST_GET_FEATURES, VHOST_SET_BACKEND_FEATURES, VHOST_SET_FEATURES,
VHOST_SET_OWNER, VHOST_SET_VRING_ADDR, VHOST_SET_VRING_BASE, VHOST_SET_VRING_CALL,
VHOST_SET_VRING_KICK, VHOST_SET_VRING_NUM, VHOST_VDPA_GET_CONFIG, VHOST_VDPA_GET_CONFIG_SIZE,
VHOST_VDPA_GET_DEVICE_ID, VHOST_VDPA_GET_IOVA_RANGE, VHOST_VDPA_GET_STATUS,
VHOST_VDPA_GET_VRING_NUM, VHOST_VDPA_SET_CONFIG, VHOST_VDPA_SET_CONFIG_CALL,
VHOST_VDPA_SET_STATUS, VHOST_VDPA_SET_VRING_ENABLE, VHOST_VDPA_SUSPEND,
};
pub enum Thread {
HttpApi,
@ -40,44 +54,6 @@ macro_rules! or {
($($x:expr),*) => (vec![$($x),*])
}
// See include/uapi/asm-generic/ioctls.h in the kernel code.
const TCGETS: u64 = 0x5401;
const TCGETS2: u64 = 0x802c_542a;
const TCSETS: u64 = 0x5402;
const TCSETS2: u64 = 0x402c_542b;
const TIOCSCTTY: u64 = 0x540E;
const TIOCGPGRP: u64 = 0x540F;
const TIOCSPGRP: u64 = 0x5410;
const TIOCGWINSZ: u64 = 0x5413;
const TIOCSPTLCK: u64 = 0x4004_5431;
const TIOCGPTPEER: u64 = 0x5441;
const FIOCLEX: u64 = 0x5451;
const FIONBIO: u64 = 0x5421;
// See include/uapi/linux/fs.h in the kernel code.
const BLKSSZGET: u64 = 0x1268;
const BLKPBSZGET: u64 = 0x127b;
const BLKIOMIN: u64 = 0x1278;
const BLKIOOPT: u64 = 0x1279;
// See include/uapi/linux/if_tun.h in the kernel code.
const TUNGETIFF: u64 = 0x8004_54d2;
const TUNSETIFF: u64 = 0x4004_54ca;
const TUNSETOFFLOAD: u64 = 0x4004_54d0;
const TUNSETVNETHDRSZ: u64 = 0x4004_54d8;
const TUNGETFEATURES: u64 = 0x8004_54cf;
// See include/uapi/linux/sockios.h in the kernel code.
const SIOCGIFFLAGS: u64 = 0x8913;
const SIOCSIFFLAGS: u64 = 0x8914;
const SIOCSIFADDR: u64 = 0x8916;
const SIOCSIFNETMASK: u64 = 0x891c;
const SIOCGIFMTU: u64 = 0x8921;
const SIOCSIFMTU: u64 = 0x8922;
const SIOCSIFHWADDR: u64 = 0x8924;
const SIOCGIFHWADDR: u64 = 0x8927;
const SIOCGIFINDEX: u64 = 0x8933;
// See include/uapi/linux/vfio.h in the kernel code.
const VFIO_GET_API_VERSION: u64 = 0x3b64;
const VFIO_CHECK_EXTENSION: u64 = 0x3b65;
@ -95,29 +71,6 @@ const VFIO_IOMMU_MAP_DMA: u64 = 0x3b71;
const VFIO_IOMMU_UNMAP_DMA: u64 = 0x3b72;
const VFIO_DEVICE_IOEVENTFD: u64 = 0x3b74;
// See include/uapi/linux/vhost.h in the kernel code
const VHOST_GET_FEATURES: u64 = 0x8008af00;
const VHOST_SET_FEATURES: u64 = 0x4008af00;
const VHOST_SET_OWNER: u64 = 0xaf01;
const VHOST_SET_VRING_NUM: u64 = 0x4008af10;
const VHOST_SET_VRING_ADDR: u64 = 0x4028af11;
const VHOST_SET_VRING_BASE: u64 = 0x4008af12;
const VHOST_SET_VRING_KICK: u64 = 0x4008af20;
const VHOST_SET_VRING_CALL: u64 = 0x4008af21;
const VHOST_SET_BACKEND_FEATURES: u64 = 0x4008af25;
const VHOST_GET_BACKEND_FEATURES: u64 = 0x8008af26;
const VHOST_VDPA_GET_DEVICE_ID: u64 = 0x8004af70;
const VHOST_VDPA_GET_STATUS: u64 = 0x8001af71;
const VHOST_VDPA_SET_STATUS: u64 = 0x4001af72;
const VHOST_VDPA_GET_CONFIG: u64 = 0x8008af73;
const VHOST_VDPA_SET_CONFIG: u64 = 0x4008af74;
const VHOST_VDPA_SET_VRING_ENABLE: u64 = 0x4008af75;
const VHOST_VDPA_GET_VRING_NUM: u64 = 0x8002af76;
const VHOST_VDPA_SET_CONFIG_CALL: u64 = 0x4004af77;
const VHOST_VDPA_GET_IOVA_RANGE: u64 = 0x8010af78;
const VHOST_VDPA_GET_CONFIG_SIZE: u64 = 0x8004af79;
const VHOST_VDPA_SUSPEND: u64 = 0xaf7d;
// See include/uapi/linux/kvm.h in the kernel code.
#[cfg(feature = "kvm")]
mod kvm {
@ -297,12 +250,12 @@ fn create_vmm_ioctl_seccomp_rule_common(
hypervisor_type: HypervisorType,
) -> Result<Vec<SeccompRule>, BackendError> {
let mut common_rules = or![
and![Cond::new(1, ArgLen::Dword, Eq, BLKSSZGET)?],
and![Cond::new(1, ArgLen::Dword, Eq, BLKPBSZGET)?],
and![Cond::new(1, ArgLen::Dword, Eq, BLKIOMIN)?],
and![Cond::new(1, ArgLen::Dword, Eq, BLKIOOPT)?],
and![Cond::new(1, ArgLen::Dword, Eq, FIOCLEX)?],
and![Cond::new(1, ArgLen::Dword, Eq, FIONBIO)?],
and![Cond::new(1, ArgLen::Dword, Eq, BLKSSZGET as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, BLKPBSZGET as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, BLKIOMIN as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, BLKIOOPT as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, FIOCLEX as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, FIONBIO as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, SIOCGIFFLAGS)?],
and![Cond::new(1, ArgLen::Dword, Eq, SIOCGIFHWADDR)?],
and![Cond::new(1, ArgLen::Dword, Eq, SIOCGIFMTU)?],
@ -312,21 +265,21 @@ fn create_vmm_ioctl_seccomp_rule_common(
and![Cond::new(1, ArgLen::Dword, Eq, SIOCSIFHWADDR)?],
and![Cond::new(1, ArgLen::Dword, Eq, SIOCSIFMTU)?],
and![Cond::new(1, ArgLen::Dword, Eq, SIOCSIFNETMASK)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCSETS)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCSETS2)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCGETS)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCGETS2)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGPGRP)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGPTPEER)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGWINSZ)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCSCTTY)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCSPGRP)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCSPTLCK)?],
and![Cond::new(1, ArgLen::Dword, Eq, TUNGETFEATURES)?],
and![Cond::new(1, ArgLen::Dword, Eq, TUNGETIFF)?],
and![Cond::new(1, ArgLen::Dword, Eq, TUNSETIFF)?],
and![Cond::new(1, ArgLen::Dword, Eq, TUNSETOFFLOAD)?],
and![Cond::new(1, ArgLen::Dword, Eq, TUNSETVNETHDRSZ)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCSETS as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCSETS2 as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCGETS as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCGETS2 as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGPGRP as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGPTPEER as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGWINSZ as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCSCTTY as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCSPGRP as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCSPTLCK as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TUNGETFEATURES as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TUNGETIFF as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TUNSETIFF as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TUNSETOFFLOAD as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TUNSETVNETHDRSZ as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, VFIO_GET_API_VERSION)?],
and![Cond::new(1, ArgLen::Dword, Eq, VFIO_CHECK_EXTENSION)?],
and![Cond::new(1, ArgLen::Dword, Eq, VFIO_SET_IOMMU)?],
@ -347,32 +300,57 @@ fn create_vmm_ioctl_seccomp_rule_common(
and![Cond::new(1, ArgLen::Dword, Eq, VFIO_IOMMU_MAP_DMA)?],
and![Cond::new(1, ArgLen::Dword, Eq, VFIO_IOMMU_UNMAP_DMA)?],
and![Cond::new(1, ArgLen::Dword, Eq, VFIO_DEVICE_IOEVENTFD)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_GET_FEATURES)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_FEATURES)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_OWNER)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_NUM)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_ADDR)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_BASE)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_KICK)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_CALL)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_BACKEND_FEATURES)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_GET_BACKEND_FEATURES)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_DEVICE_ID)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_STATUS)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SET_STATUS)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_CONFIG)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SET_CONFIG)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_GET_FEATURES())?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_FEATURES())?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_OWNER())?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_NUM())?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_ADDR())?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_BASE())?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_KICK())?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_CALL())?],
and![Cond::new(
1,
ArgLen::Dword,
Eq,
VHOST_VDPA_SET_VRING_ENABLE
VHOST_SET_BACKEND_FEATURES()
)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_VRING_NUM)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SET_CONFIG_CALL)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_IOVA_RANGE)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_CONFIG_SIZE)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SUSPEND)?],
and![Cond::new(
1,
ArgLen::Dword,
Eq,
VHOST_GET_BACKEND_FEATURES()
)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_DEVICE_ID())?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_STATUS())?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SET_STATUS())?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_CONFIG())?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SET_CONFIG())?],
and![Cond::new(
1,
ArgLen::Dword,
Eq,
VHOST_VDPA_SET_VRING_ENABLE(),
)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_VRING_NUM())?],
and![Cond::new(
1,
ArgLen::Dword,
Eq,
VHOST_VDPA_SET_CONFIG_CALL()
)?],
and![Cond::new(
1,
ArgLen::Dword,
Eq,
VHOST_VDPA_GET_IOVA_RANGE()
)?],
and![Cond::new(
1,
ArgLen::Dword,
Eq,
VHOST_VDPA_GET_CONFIG_SIZE()
)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SUSPEND())?],
];
let hypervisor_rules = create_vmm_ioctl_seccomp_rule_hypervisor(hypervisor_type)?;
@ -485,16 +463,16 @@ fn create_vmm_ioctl_seccomp_rule(
}
fn create_api_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, BackendError> {
Ok(or![and![Cond::new(1, ArgLen::Dword, Eq, FIONBIO)?]])
Ok(or![and![Cond::new(1, ArgLen::Dword, Eq, FIONBIO as _)?]])
}
fn create_signal_handler_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, BackendError> {
Ok(or![
and![Cond::new(1, ArgLen::Dword, Eq, TCGETS)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCGETS2)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCSETS)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCSETS2)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGWINSZ)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCGETS as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCGETS2 as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCSETS as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TCSETS2 as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGWINSZ as _)?],
])
}
@ -526,9 +504,9 @@ fn signal_handler_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, Backend
fn create_pty_foreground_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, BackendError> {
Ok(or![
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGPGRP)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCSCTTY)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCSPGRP)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCGPGRP as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCSCTTY as _)?],
and![Cond::new(1, ArgLen::Dword, Eq, TIOCSPGRP as _)?],
])
}
@ -773,14 +751,14 @@ fn create_vcpu_ioctl_seccomp_rule(
and![Cond::new(1, ArgLen::Dword, Eq, VFIO_GROUP_UNSET_CONTAINER)?],
and![Cond::new(1, ArgLen::Dword, Eq, VFIO_IOMMU_MAP_DMA)?],
and![Cond::new(1, ArgLen::Dword, Eq, VFIO_IOMMU_UNMAP_DMA)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SET_STATUS)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_CONFIG)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SET_CONFIG)?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SET_STATUS())?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_CONFIG())?],
and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SET_CONFIG())?],
and![Cond::new(
1,
ArgLen::Dword,
Eq,
VHOST_VDPA_SET_VRING_ENABLE
VHOST_VDPA_SET_VRING_ENABLE(),
)?],
];