xref: /cloud-hypervisor/vmm/src/seccomp_filters.rs (revision d580ed55c6b0785aecae9de400f3dab484bb4bd6)
1 // Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 //
3 // Copyright © 2020 Intel Corporation
4 //
5 // SPDX-License-Identifier: Apache-2.0
6 
7 use hypervisor::HypervisorType;
8 use seccompiler::SeccompCmpOp::Eq;
9 use seccompiler::{
10     BackendError, BpfProgram, Error, SeccompAction, SeccompCmpArgLen as ArgLen,
11     SeccompCondition as Cond, SeccompFilter, SeccompRule,
12 };
13 
14 pub enum Thread {
15     HttpApi,
16     #[cfg(feature = "dbus_api")]
17     DBusApi,
18     EventMonitor,
19     SignalHandler,
20     Vcpu,
21     Vmm,
22     PtyForeground,
23 }
24 
25 /// Shorthand for chaining `SeccompCondition`s with the `and` operator  in a `SeccompRule`.
26 /// The rule will take the `Allow` action if _all_ the conditions are true.
27 ///
28 /// [`SeccompCondition`]: struct.SeccompCondition.html
29 /// [`SeccompRule`]: struct.SeccompRule.html
30 macro_rules! and {
31     ($($x:expr),*) => (SeccompRule::new(vec![$($x),*]).unwrap())
32 }
33 
34 /// Shorthand for chaining `SeccompRule`s with the `or` operator in a `SeccompFilter`.
35 ///
36 /// [`SeccompFilter`]: struct.SeccompFilter.html
37 /// [`SeccompRule`]: struct.SeccompRule.html
38 macro_rules! or {
39     ($($x:expr,)*) => (vec![$($x),*]);
40     ($($x:expr),*) => (vec![$($x),*])
41 }
42 
43 // See include/uapi/asm-generic/ioctls.h in the kernel code.
44 const TCGETS: u64 = 0x5401;
45 const TCSETS: u64 = 0x5402;
46 const TIOCSCTTY: u64 = 0x540E;
47 const TIOCGPGRP: u64 = 0x540F;
48 const TIOCSPGRP: u64 = 0x5410;
49 const TIOCGWINSZ: u64 = 0x5413;
50 const TIOCSPTLCK: u64 = 0x4004_5431;
51 const TIOCGPTPEER: u64 = 0x5441;
52 const FIOCLEX: u64 = 0x5451;
53 const FIONBIO: u64 = 0x5421;
54 
55 // See include/uapi/linux/fs.h in the kernel code.
56 const BLKSSZGET: u64 = 0x1268;
57 const BLKPBSZGET: u64 = 0x127b;
58 const BLKIOMIN: u64 = 0x1278;
59 const BLKIOOPT: u64 = 0x1279;
60 
61 // See include/uapi/linux/if_tun.h in the kernel code.
62 const TUNGETIFF: u64 = 0x8004_54d2;
63 const TUNSETIFF: u64 = 0x4004_54ca;
64 const TUNSETOFFLOAD: u64 = 0x4004_54d0;
65 const TUNSETVNETHDRSZ: u64 = 0x4004_54d8;
66 const TUNGETFEATURES: u64 = 0x8004_54cf;
67 
68 // See include/uapi/linux/sockios.h in the kernel code.
69 const SIOCGIFFLAGS: u64 = 0x8913;
70 const SIOCSIFFLAGS: u64 = 0x8914;
71 const SIOCSIFADDR: u64 = 0x8916;
72 const SIOCSIFNETMASK: u64 = 0x891c;
73 const SIOCGIFMTU: u64 = 0x8921;
74 const SIOCSIFMTU: u64 = 0x8922;
75 const SIOCSIFHWADDR: u64 = 0x8924;
76 const SIOCGIFHWADDR: u64 = 0x8927;
77 const SIOCGIFINDEX: u64 = 0x8933;
78 
79 // See include/uapi/linux/vfio.h in the kernel code.
80 const VFIO_GET_API_VERSION: u64 = 0x3b64;
81 const VFIO_CHECK_EXTENSION: u64 = 0x3b65;
82 const VFIO_SET_IOMMU: u64 = 0x3b66;
83 const VFIO_GROUP_GET_STATUS: u64 = 0x3b67;
84 const VFIO_GROUP_SET_CONTAINER: u64 = 0x3b68;
85 const VFIO_GROUP_UNSET_CONTAINER: u64 = 0x3b69;
86 const VFIO_GROUP_GET_DEVICE_FD: u64 = 0x3b6a;
87 const VFIO_DEVICE_GET_INFO: u64 = 0x3b6b;
88 const VFIO_DEVICE_GET_REGION_INFO: u64 = 0x3b6c;
89 const VFIO_DEVICE_GET_IRQ_INFO: u64 = 0x3b6d;
90 const VFIO_DEVICE_SET_IRQS: u64 = 0x3b6e;
91 const VFIO_DEVICE_RESET: u64 = 0x3b6f;
92 const VFIO_IOMMU_MAP_DMA: u64 = 0x3b71;
93 const VFIO_IOMMU_UNMAP_DMA: u64 = 0x3b72;
94 const VFIO_DEVICE_IOEVENTFD: u64 = 0x3b74;
95 
96 // See include/uapi/linux/vhost.h in the kernel code
97 const VHOST_GET_FEATURES: u64 = 0x8008af00;
98 const VHOST_SET_FEATURES: u64 = 0x4008af00;
99 const VHOST_SET_OWNER: u64 = 0xaf01;
100 const VHOST_SET_VRING_NUM: u64 = 0x4008af10;
101 const VHOST_SET_VRING_ADDR: u64 = 0x4028af11;
102 const VHOST_SET_VRING_BASE: u64 = 0x4008af12;
103 const VHOST_SET_VRING_KICK: u64 = 0x4008af20;
104 const VHOST_SET_VRING_CALL: u64 = 0x4008af21;
105 const VHOST_SET_BACKEND_FEATURES: u64 = 0x4008af25;
106 const VHOST_GET_BACKEND_FEATURES: u64 = 0x8008af26;
107 const VHOST_VDPA_GET_DEVICE_ID: u64 = 0x8004af70;
108 const VHOST_VDPA_GET_STATUS: u64 = 0x8001af71;
109 const VHOST_VDPA_SET_STATUS: u64 = 0x4001af72;
110 const VHOST_VDPA_GET_CONFIG: u64 = 0x8008af73;
111 const VHOST_VDPA_SET_CONFIG: u64 = 0x4008af74;
112 const VHOST_VDPA_SET_VRING_ENABLE: u64 = 0x4008af75;
113 const VHOST_VDPA_GET_VRING_NUM: u64 = 0x8002af76;
114 const VHOST_VDPA_SET_CONFIG_CALL: u64 = 0x4004af77;
115 const VHOST_VDPA_GET_IOVA_RANGE: u64 = 0x8010af78;
116 const VHOST_VDPA_GET_CONFIG_SIZE: u64 = 0x8004af79;
117 const VHOST_VDPA_SUSPEND: u64 = 0xaf7d;
118 
119 // See include/uapi/linux/kvm.h in the kernel code.
120 #[cfg(feature = "kvm")]
121 mod kvm {
122     pub const KVM_GET_API_VERSION: u64 = 0xae00;
123     pub const KVM_CREATE_VM: u64 = 0xae01;
124     pub const KVM_CHECK_EXTENSION: u64 = 0xae03;
125     pub const KVM_GET_VCPU_MMAP_SIZE: u64 = 0xae04;
126     pub const KVM_CREATE_VCPU: u64 = 0xae41;
127     pub const KVM_CREATE_IRQCHIP: u64 = 0xae60;
128     pub const KVM_RUN: u64 = 0xae80;
129     pub const KVM_SET_MP_STATE: u64 = 0x4004_ae99;
130     pub const KVM_SET_GSI_ROUTING: u64 = 0x4008_ae6a;
131     pub const KVM_SET_DEVICE_ATTR: u64 = 0x4018_aee1;
132     pub const KVM_HAS_DEVICE_ATTR: u64 = 0x4018_aee3;
133     pub const KVM_SET_ONE_REG: u64 = 0x4010_aeac;
134     pub const KVM_SET_USER_MEMORY_REGION: u64 = 0x4020_ae46;
135     pub const KVM_IRQFD: u64 = 0x4020_ae76;
136     pub const KVM_IOEVENTFD: u64 = 0x4040_ae79;
137     pub const KVM_SET_VCPU_EVENTS: u64 = 0x4040_aea0;
138     pub const KVM_ENABLE_CAP: u64 = 0x4068_aea3;
139     pub const KVM_SET_REGS: u64 = 0x4090_ae82;
140     pub const KVM_GET_MP_STATE: u64 = 0x8004_ae98;
141     pub const KVM_GET_DEVICE_ATTR: u64 = 0x4018_aee2;
142     pub const KVM_GET_DIRTY_LOG: u64 = 0x4010_ae42;
143     pub const KVM_GET_VCPU_EVENTS: u64 = 0x8040_ae9f;
144     pub const KVM_GET_ONE_REG: u64 = 0x4010_aeab;
145     pub const KVM_GET_REGS: u64 = 0x8090_ae81;
146     pub const KVM_GET_SUPPORTED_CPUID: u64 = 0xc008_ae05;
147     pub const KVM_CREATE_DEVICE: u64 = 0xc00c_aee0;
148     pub const KVM_GET_REG_LIST: u64 = 0xc008_aeb0;
149     pub const KVM_MEMORY_ENCRYPT_OP: u64 = 0xc008_aeba;
150     pub const KVM_NMI: u64 = 0xae9a;
151 }
152 
153 // MSHV IOCTL code. This is unstable until the kernel code has been declared stable.
154 #[cfg(feature = "mshv")]
155 use hypervisor::mshv::mshv_ioctls::*;
156 #[cfg(feature = "kvm")]
157 use kvm::*;
158 
159 #[cfg(feature = "mshv")]
create_vmm_ioctl_seccomp_rule_common_mshv() -> Result<Vec<SeccompRule>, BackendError>160 fn create_vmm_ioctl_seccomp_rule_common_mshv() -> Result<Vec<SeccompRule>, BackendError> {
161     Ok(or![
162         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_CREATE_PARTITION())?],
163         and![Cond::new(
164             1,
165             ArgLen::Dword,
166             Eq,
167             MSHV_INITIALIZE_PARTITION()
168         )?],
169         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_GUEST_MEMORY())?],
170         and![Cond::new(
171             1,
172             ArgLen::Dword,
173             Eq,
174             MSHV_GET_HOST_PARTITION_PROPERTY()
175         )?],
176         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_CREATE_VP())?],
177         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_IRQFD())?],
178         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_IOEVENTFD())?],
179         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_MSI_ROUTING())?],
180         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_GET_VP_REGISTERS())?],
181         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_VP_REGISTERS())?],
182         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_RUN_VP())?],
183         #[cfg(target_arch = "x86_64")]
184         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_GET_VP_STATE())?],
185         #[cfg(target_arch = "x86_64")]
186         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_VP_STATE())?],
187         and![Cond::new(
188             1,
189             ArgLen::Dword,
190             Eq,
191             MSHV_SET_PARTITION_PROPERTY()
192         )?],
193         and![Cond::new(
194             1,
195             ArgLen::Dword,
196             Eq,
197             MSHV_GET_PARTITION_PROPERTY()
198         )?],
199         and![Cond::new(
200             1,
201             ArgLen::Dword,
202             Eq,
203             MSHV_GET_GPAP_ACCESS_BITMAP()
204         )?],
205         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_VP_TRANSLATE_GVA())?],
206         #[cfg(target_arch = "x86_64")]
207         and![Cond::new(
208             1,
209             ArgLen::Dword,
210             Eq,
211             MSHV_VP_REGISTER_INTERCEPT_RESULT()
212         )?],
213         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_CREATE_DEVICE())?],
214         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_DEVICE_ATTR())?],
215         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_GET_VP_CPUID_VALUES())?],
216         and![Cond::new(
217             1,
218             ArgLen::Dword,
219             Eq,
220             MSHV_MODIFY_GPA_HOST_ACCESS()
221         )?],
222         and![Cond::new(
223             1,
224             ArgLen::Dword,
225             Eq,
226             MSHV_IMPORT_ISOLATED_PAGES()
227         )?],
228         and![Cond::new(
229             1,
230             ArgLen::Dword,
231             Eq,
232             MSHV_COMPLETE_ISOLATED_IMPORT()
233         )?],
234         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_READ_GPA())?],
235         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_WRITE_GPA())?],
236         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SEV_SNP_AP_CREATE())?],
237         and![Cond::new(
238             1,
239             ArgLen::Dword,
240             Eq,
241             MSHV_ISSUE_PSP_GUEST_REQUEST()
242         )?],
243         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_ROOT_HVCALL())?],
244         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_ASSERT_INTERRUPT())?],
245     ])
246 }
247 
248 #[cfg(feature = "kvm")]
create_vmm_ioctl_seccomp_rule_common_kvm() -> Result<Vec<SeccompRule>, BackendError>249 fn create_vmm_ioctl_seccomp_rule_common_kvm() -> Result<Vec<SeccompRule>, BackendError> {
250     Ok(or![
251         and![Cond::new(1, ArgLen::Dword, Eq, KVM_CHECK_EXTENSION)?],
252         and![Cond::new(1, ArgLen::Dword, Eq, KVM_CREATE_DEVICE,)?],
253         and![Cond::new(1, ArgLen::Dword, Eq, KVM_CREATE_IRQCHIP,)?],
254         and![Cond::new(1, ArgLen::Dword, Eq, KVM_CREATE_VCPU)?],
255         and![Cond::new(1, ArgLen::Dword, Eq, KVM_CREATE_VM)?],
256         and![Cond::new(1, ArgLen::Dword, Eq, KVM_ENABLE_CAP)?],
257         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_API_VERSION,)?],
258         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_DEVICE_ATTR,)?],
259         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_DIRTY_LOG)?],
260         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_MP_STATE)?],
261         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_ONE_REG)?],
262         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_REGS)?],
263         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_REG_LIST)?],
264         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_SUPPORTED_CPUID,)?],
265         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_VCPU_EVENTS,)?],
266         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_VCPU_MMAP_SIZE,)?],
267         and![Cond::new(1, ArgLen::Dword, Eq, KVM_IOEVENTFD)?],
268         and![Cond::new(1, ArgLen::Dword, Eq, KVM_IRQFD)?],
269         and![Cond::new(1, ArgLen::Dword, Eq, KVM_RUN)?],
270         and![Cond::new(1, ArgLen::Dword, Eq, KVM_MEMORY_ENCRYPT_OP)?],
271         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_DEVICE_ATTR,)?],
272         and![Cond::new(1, ArgLen::Dword, Eq, KVM_HAS_DEVICE_ATTR,)?],
273         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_GSI_ROUTING)?],
274         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_MP_STATE)?],
275         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_ONE_REG)?],
276         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_REGS)?],
277         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_USER_MEMORY_REGION,)?],
278         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_VCPU_EVENTS,)?],
279         and![Cond::new(1, ArgLen::Dword, Eq, KVM_NMI)?],
280     ])
281 }
282 
create_vmm_ioctl_seccomp_rule_hypervisor( hypervisor_type: HypervisorType, ) -> Result<Vec<SeccompRule>, BackendError>283 fn create_vmm_ioctl_seccomp_rule_hypervisor(
284     hypervisor_type: HypervisorType,
285 ) -> Result<Vec<SeccompRule>, BackendError> {
286     match hypervisor_type {
287         #[cfg(feature = "kvm")]
288         HypervisorType::Kvm => create_vmm_ioctl_seccomp_rule_common_kvm(),
289         #[cfg(feature = "mshv")]
290         HypervisorType::Mshv => create_vmm_ioctl_seccomp_rule_common_mshv(),
291     }
292 }
293 
create_vmm_ioctl_seccomp_rule_common( hypervisor_type: HypervisorType, ) -> Result<Vec<SeccompRule>, BackendError>294 fn create_vmm_ioctl_seccomp_rule_common(
295     hypervisor_type: HypervisorType,
296 ) -> Result<Vec<SeccompRule>, BackendError> {
297     let mut common_rules = or![
298         and![Cond::new(1, ArgLen::Dword, Eq, BLKSSZGET)?],
299         and![Cond::new(1, ArgLen::Dword, Eq, BLKPBSZGET)?],
300         and![Cond::new(1, ArgLen::Dword, Eq, BLKIOMIN)?],
301         and![Cond::new(1, ArgLen::Dword, Eq, BLKIOOPT)?],
302         and![Cond::new(1, ArgLen::Dword, Eq, FIOCLEX)?],
303         and![Cond::new(1, ArgLen::Dword, Eq, FIONBIO)?],
304         and![Cond::new(1, ArgLen::Dword, Eq, SIOCGIFFLAGS)?],
305         and![Cond::new(1, ArgLen::Dword, Eq, SIOCGIFHWADDR)?],
306         and![Cond::new(1, ArgLen::Dword, Eq, SIOCGIFMTU)?],
307         and![Cond::new(1, ArgLen::Dword, Eq, SIOCGIFINDEX)?],
308         and![Cond::new(1, ArgLen::Dword, Eq, SIOCSIFADDR)?],
309         and![Cond::new(1, ArgLen::Dword, Eq, SIOCSIFFLAGS)?],
310         and![Cond::new(1, ArgLen::Dword, Eq, SIOCSIFHWADDR)?],
311         and![Cond::new(1, ArgLen::Dword, Eq, SIOCSIFMTU)?],
312         and![Cond::new(1, ArgLen::Dword, Eq, SIOCSIFNETMASK)?],
313         and![Cond::new(1, ArgLen::Dword, Eq, TCSETS)?],
314         and![Cond::new(1, ArgLen::Dword, Eq, TCGETS)?],
315         and![Cond::new(1, ArgLen::Dword, Eq, TIOCGPGRP)?],
316         and![Cond::new(1, ArgLen::Dword, Eq, TIOCGPTPEER)?],
317         and![Cond::new(1, ArgLen::Dword, Eq, TIOCGWINSZ)?],
318         and![Cond::new(1, ArgLen::Dword, Eq, TIOCSCTTY)?],
319         and![Cond::new(1, ArgLen::Dword, Eq, TIOCSPGRP)?],
320         and![Cond::new(1, ArgLen::Dword, Eq, TIOCSPTLCK)?],
321         and![Cond::new(1, ArgLen::Dword, Eq, TUNGETFEATURES)?],
322         and![Cond::new(1, ArgLen::Dword, Eq, TUNGETIFF)?],
323         and![Cond::new(1, ArgLen::Dword, Eq, TUNSETIFF)?],
324         and![Cond::new(1, ArgLen::Dword, Eq, TUNSETOFFLOAD)?],
325         and![Cond::new(1, ArgLen::Dword, Eq, TUNSETVNETHDRSZ)?],
326         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_GET_API_VERSION)?],
327         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_CHECK_EXTENSION)?],
328         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_SET_IOMMU)?],
329         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_GROUP_GET_STATUS)?],
330         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_GROUP_SET_CONTAINER)?],
331         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_GROUP_UNSET_CONTAINER)?],
332         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_GROUP_GET_DEVICE_FD)?],
333         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_DEVICE_GET_INFO)?],
334         and![Cond::new(
335             1,
336             ArgLen::Dword,
337             Eq,
338             VFIO_DEVICE_GET_REGION_INFO
339         )?],
340         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_DEVICE_GET_IRQ_INFO)?],
341         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_DEVICE_SET_IRQS)?],
342         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_DEVICE_RESET)?],
343         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_IOMMU_MAP_DMA)?],
344         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_IOMMU_UNMAP_DMA)?],
345         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_DEVICE_IOEVENTFD)?],
346         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_GET_FEATURES)?],
347         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_FEATURES)?],
348         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_OWNER)?],
349         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_NUM)?],
350         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_ADDR)?],
351         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_BASE)?],
352         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_KICK)?],
353         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_VRING_CALL)?],
354         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_SET_BACKEND_FEATURES)?],
355         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_GET_BACKEND_FEATURES)?],
356         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_DEVICE_ID)?],
357         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_STATUS)?],
358         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SET_STATUS)?],
359         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_CONFIG)?],
360         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SET_CONFIG)?],
361         and![Cond::new(
362             1,
363             ArgLen::Dword,
364             Eq,
365             VHOST_VDPA_SET_VRING_ENABLE
366         )?],
367         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_VRING_NUM)?],
368         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SET_CONFIG_CALL)?],
369         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_IOVA_RANGE)?],
370         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_CONFIG_SIZE)?],
371         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SUSPEND)?],
372     ];
373 
374     let hypervisor_rules = create_vmm_ioctl_seccomp_rule_hypervisor(hypervisor_type)?;
375 
376     common_rules.extend(hypervisor_rules);
377 
378     Ok(common_rules)
379 }
380 
381 #[cfg(all(target_arch = "x86_64", feature = "kvm"))]
create_vmm_ioctl_seccomp_rule_kvm() -> Result<Vec<SeccompRule>, BackendError>382 fn create_vmm_ioctl_seccomp_rule_kvm() -> Result<Vec<SeccompRule>, BackendError> {
383     const KVM_CREATE_PIT2: u64 = 0x4040_ae77;
384     const KVM_GET_CLOCK: u64 = 0x8030_ae7c;
385     const KVM_GET_CPUID2: u64 = 0xc008_ae91;
386     const KVM_GET_FPU: u64 = 0x81a0_ae8c;
387     const KVM_GET_LAPIC: u64 = 0x8400_ae8e;
388     const KVM_GET_MSR_INDEX_LIST: u64 = 0xc004_ae02;
389     const KVM_GET_MSRS: u64 = 0xc008_ae88;
390     const KVM_GET_SREGS: u64 = 0x8138_ae83;
391     const KVM_GET_TSC_KHZ: u64 = 0xaea3;
392     const KVM_GET_XCRS: u64 = 0x8188_aea6;
393     const KVM_GET_XSAVE: u64 = 0x9000_aea4;
394     const KVM_KVMCLOCK_CTRL: u64 = 0xaead;
395     const KVM_SET_CLOCK: u64 = 0x4030_ae7b;
396     const KVM_SET_CPUID2: u64 = 0x4008_ae90;
397     const KVM_SET_FPU: u64 = 0x41a0_ae8d;
398     const KVM_SET_IDENTITY_MAP_ADDR: u64 = 0x4008_ae48;
399     const KVM_SET_LAPIC: u64 = 0x4400_ae8f;
400     const KVM_SET_MSRS: u64 = 0x4008_ae89;
401     const KVM_SET_SREGS: u64 = 0x4138_ae84;
402     const KVM_SET_TSC_KHZ: u64 = 0xaea2;
403     const KVM_SET_TSS_ADDR: u64 = 0xae47;
404     const KVM_SET_XCRS: u64 = 0x4188_aea7;
405     const KVM_SET_XSAVE: u64 = 0x5000_aea5;
406     const KVM_SET_GUEST_DEBUG: u64 = 0x4048_ae9b;
407     const KVM_TRANSLATE: u64 = 0xc018_ae85;
408 
409     let common_rules = create_vmm_ioctl_seccomp_rule_common(HypervisorType::Kvm)?;
410     let mut arch_rules = or![
411         and![Cond::new(1, ArgLen::Dword, Eq, KVM_CREATE_PIT2)?],
412         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_CLOCK,)?],
413         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_CPUID2,)?],
414         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_FPU)?],
415         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_LAPIC)?],
416         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_MSR_INDEX_LIST)?],
417         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_MSRS)?],
418         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_SREGS)?],
419         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_TSC_KHZ)?],
420         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_XCRS,)?],
421         and![Cond::new(1, ArgLen::Dword, Eq, KVM_GET_XSAVE,)?],
422         and![Cond::new(1, ArgLen::Dword, Eq, KVM_KVMCLOCK_CTRL)?],
423         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_CLOCK)?],
424         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_CPUID2)?],
425         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_FPU)?],
426         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_IDENTITY_MAP_ADDR)?],
427         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_LAPIC)?],
428         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_SREGS)?],
429         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_TSC_KHZ)?],
430         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_TSS_ADDR,)?],
431         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_MSRS)?],
432         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_XCRS,)?],
433         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_XSAVE,)?],
434         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_GUEST_DEBUG,)?],
435         and![Cond::new(1, ArgLen::Dword, Eq, KVM_TRANSLATE,)?],
436     ];
437     arch_rules.extend(common_rules);
438 
439     Ok(arch_rules)
440 }
441 
442 #[cfg(all(target_arch = "aarch64", feature = "kvm"))]
create_vmm_ioctl_seccomp_rule_kvm() -> Result<Vec<SeccompRule>, BackendError>443 fn create_vmm_ioctl_seccomp_rule_kvm() -> Result<Vec<SeccompRule>, BackendError> {
444     const KVM_ARM_PREFERRED_TARGET: u64 = 0x8020_aeaf;
445     const KVM_ARM_VCPU_INIT: u64 = 0x4020_aeae;
446     const KVM_SET_GUEST_DEBUG: u64 = 0x4208_ae9b;
447     const KVM_ARM_VCPU_FINALIZE: u64 = 0x4004_aec2;
448 
449     let common_rules = create_vmm_ioctl_seccomp_rule_common(HypervisorType::Kvm)?;
450     let mut arch_rules = or![
451         and![Cond::new(1, ArgLen::Dword, Eq, KVM_ARM_PREFERRED_TARGET,)?],
452         and![Cond::new(1, ArgLen::Dword, Eq, KVM_ARM_VCPU_INIT,)?],
453         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_GUEST_DEBUG,)?],
454         and![Cond::new(1, ArgLen::Dword, Eq, KVM_ARM_VCPU_FINALIZE,)?],
455     ];
456     arch_rules.extend(common_rules);
457 
458     Ok(arch_rules)
459 }
460 
461 #[cfg(all(target_arch = "riscv64", feature = "kvm"))]
create_vmm_ioctl_seccomp_rule_kvm() -> Result<Vec<SeccompRule>, BackendError>462 fn create_vmm_ioctl_seccomp_rule_kvm() -> Result<Vec<SeccompRule>, BackendError> {
463     let common_rules = create_vmm_ioctl_seccomp_rule_common(HypervisorType::Kvm)?;
464     Ok(common_rules)
465 }
466 
467 #[cfg(feature = "mshv")]
create_vmm_ioctl_seccomp_rule_mshv() -> Result<Vec<SeccompRule>, BackendError>468 fn create_vmm_ioctl_seccomp_rule_mshv() -> Result<Vec<SeccompRule>, BackendError> {
469     create_vmm_ioctl_seccomp_rule_common(HypervisorType::Mshv)
470 }
471 
create_vmm_ioctl_seccomp_rule( hypervisor_type: HypervisorType, ) -> Result<Vec<SeccompRule>, BackendError>472 fn create_vmm_ioctl_seccomp_rule(
473     hypervisor_type: HypervisorType,
474 ) -> Result<Vec<SeccompRule>, BackendError> {
475     match hypervisor_type {
476         #[cfg(feature = "kvm")]
477         HypervisorType::Kvm => create_vmm_ioctl_seccomp_rule_kvm(),
478         #[cfg(feature = "mshv")]
479         HypervisorType::Mshv => create_vmm_ioctl_seccomp_rule_mshv(),
480     }
481 }
482 
create_api_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, BackendError>483 fn create_api_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, BackendError> {
484     Ok(or![and![Cond::new(1, ArgLen::Dword, Eq, FIONBIO)?]])
485 }
486 
create_signal_handler_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, BackendError>487 fn create_signal_handler_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, BackendError> {
488     Ok(or![
489         and![Cond::new(1, ArgLen::Dword, Eq, TCGETS)?],
490         and![Cond::new(1, ArgLen::Dword, Eq, TCSETS)?],
491         and![Cond::new(1, ArgLen::Dword, Eq, TIOCGWINSZ)?],
492     ])
493 }
494 
signal_handler_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError>495 fn signal_handler_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError> {
496     Ok(vec![
497         (libc::SYS_brk, vec![]),
498         (libc::SYS_close, vec![]),
499         (libc::SYS_exit, vec![]),
500         (libc::SYS_exit_group, vec![]),
501         (libc::SYS_futex, vec![]),
502         (libc::SYS_ioctl, create_signal_handler_ioctl_seccomp_rule()?),
503         (libc::SYS_landlock_create_ruleset, vec![]),
504         (libc::SYS_landlock_restrict_self, vec![]),
505         (libc::SYS_madvise, vec![]),
506         (libc::SYS_mmap, vec![]),
507         (libc::SYS_munmap, vec![]),
508         (libc::SYS_prctl, vec![]),
509         (libc::SYS_recvfrom, vec![]),
510         (libc::SYS_rt_sigprocmask, vec![]),
511         (libc::SYS_rt_sigreturn, vec![]),
512         (libc::SYS_sched_yield, vec![]),
513         (libc::SYS_sendto, vec![]),
514         (libc::SYS_sigaltstack, vec![]),
515         (libc::SYS_write, vec![]),
516         #[cfg(debug_assertions)]
517         (libc::SYS_fcntl, vec![]),
518     ])
519 }
520 
create_pty_foreground_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, BackendError>521 fn create_pty_foreground_ioctl_seccomp_rule() -> Result<Vec<SeccompRule>, BackendError> {
522     Ok(or![
523         and![Cond::new(1, ArgLen::Dword, Eq, TIOCGPGRP)?],
524         and![Cond::new(1, ArgLen::Dword, Eq, TIOCSCTTY)?],
525         and![Cond::new(1, ArgLen::Dword, Eq, TIOCSPGRP)?],
526     ])
527 }
528 
pty_foreground_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError>529 fn pty_foreground_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError> {
530     Ok(vec![
531         (libc::SYS_close, vec![]),
532         (libc::SYS_exit_group, vec![]),
533         (libc::SYS_getpgid, vec![]),
534         #[cfg(target_arch = "x86_64")]
535         (libc::SYS_getpgrp, vec![]),
536         (libc::SYS_ioctl, create_pty_foreground_ioctl_seccomp_rule()?),
537         (libc::SYS_munmap, vec![]),
538         #[cfg(target_arch = "x86_64")]
539         (libc::SYS_poll, vec![]),
540         #[cfg(target_arch = "aarch64")]
541         (libc::SYS_ppoll, vec![]),
542         (libc::SYS_read, vec![]),
543         (libc::SYS_restart_syscall, vec![]),
544         (libc::SYS_rt_sigaction, vec![]),
545         (libc::SYS_rt_sigreturn, vec![]),
546         (libc::SYS_sched_yield, vec![]),
547         (libc::SYS_setsid, vec![]),
548         (libc::SYS_sigaltstack, vec![]),
549         (libc::SYS_write, vec![]),
550         #[cfg(debug_assertions)]
551         (libc::SYS_fcntl, vec![]),
552         (libc::SYS_getcwd, vec![]),
553     ])
554 }
555 
556 // The filter containing the white listed syscall rules required by the VMM to
557 // function.
vmm_thread_rules( hypervisor_type: HypervisorType, ) -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError>558 fn vmm_thread_rules(
559     hypervisor_type: HypervisorType,
560 ) -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError> {
561     Ok(vec![
562         (libc::SYS_accept4, vec![]),
563         #[cfg(target_arch = "x86_64")]
564         (libc::SYS_access, vec![]),
565         (libc::SYS_bind, vec![]),
566         (libc::SYS_brk, vec![]),
567         (libc::SYS_clock_gettime, vec![]),
568         (libc::SYS_clock_nanosleep, vec![]),
569         (libc::SYS_clone, vec![]),
570         (libc::SYS_clone3, vec![]),
571         (libc::SYS_close, vec![]),
572         (libc::SYS_close_range, vec![]),
573         (libc::SYS_connect, vec![]),
574         (libc::SYS_dup, vec![]),
575         (libc::SYS_epoll_create1, vec![]),
576         (libc::SYS_epoll_ctl, vec![]),
577         (libc::SYS_epoll_pwait, vec![]),
578         #[cfg(target_arch = "x86_64")]
579         (libc::SYS_epoll_wait, vec![]),
580         (libc::SYS_eventfd2, vec![]),
581         (libc::SYS_exit, vec![]),
582         (libc::SYS_exit_group, vec![]),
583         (libc::SYS_fallocate, vec![]),
584         (libc::SYS_fcntl, vec![]),
585         (libc::SYS_fdatasync, vec![]),
586         (libc::SYS_fstat, vec![]),
587         (libc::SYS_fsync, vec![]),
588         (libc::SYS_ftruncate, vec![]),
589         #[cfg(target_arch = "aarch64")]
590         (libc::SYS_faccessat, vec![]),
591         #[cfg(target_arch = "aarch64")]
592         (libc::SYS_newfstatat, vec![]),
593         (libc::SYS_futex, vec![]),
594         (libc::SYS_getdents64, vec![]),
595         (libc::SYS_getpgid, vec![]),
596         #[cfg(target_arch = "x86_64")]
597         (libc::SYS_getpgrp, vec![]),
598         (libc::SYS_getpid, vec![]),
599         (libc::SYS_getrandom, vec![]),
600         (libc::SYS_gettid, vec![]),
601         (libc::SYS_gettimeofday, vec![]),
602         (libc::SYS_getuid, vec![]),
603         (
604             libc::SYS_ioctl,
605             create_vmm_ioctl_seccomp_rule(hypervisor_type)?,
606         ),
607         (libc::SYS_io_cancel, vec![]),
608         (libc::SYS_io_destroy, vec![]),
609         (libc::SYS_io_getevents, vec![]),
610         (libc::SYS_io_setup, vec![]),
611         (libc::SYS_io_submit, vec![]),
612         (libc::SYS_io_uring_enter, vec![]),
613         (libc::SYS_io_uring_setup, vec![]),
614         (libc::SYS_io_uring_register, vec![]),
615         (libc::SYS_kill, vec![]),
616         (libc::SYS_landlock_create_ruleset, vec![]),
617         (libc::SYS_landlock_add_rule, vec![]),
618         (libc::SYS_landlock_restrict_self, vec![]),
619         (libc::SYS_listen, vec![]),
620         (libc::SYS_lseek, vec![]),
621         (libc::SYS_madvise, vec![]),
622         (libc::SYS_mbind, vec![]),
623         (libc::SYS_memfd_create, vec![]),
624         (libc::SYS_mmap, vec![]),
625         (libc::SYS_mprotect, vec![]),
626         (libc::SYS_mremap, vec![]),
627         (libc::SYS_munmap, vec![]),
628         (libc::SYS_nanosleep, vec![]),
629         (libc::SYS_newfstatat, vec![]),
630         #[cfg(target_arch = "x86_64")]
631         (libc::SYS_open, vec![]),
632         (libc::SYS_openat, vec![]),
633         (libc::SYS_pipe2, vec![]),
634         #[cfg(target_arch = "x86_64")]
635         (libc::SYS_poll, vec![]),
636         #[cfg(target_arch = "aarch64")]
637         (libc::SYS_ppoll, vec![]),
638         (libc::SYS_prctl, vec![]),
639         (libc::SYS_pread64, vec![]),
640         (libc::SYS_preadv, vec![]),
641         (libc::SYS_prlimit64, vec![]),
642         (libc::SYS_pwrite64, vec![]),
643         (libc::SYS_pwritev, vec![]),
644         (libc::SYS_read, vec![]),
645         (libc::SYS_readv, vec![]),
646         #[cfg(target_arch = "x86_64")]
647         (libc::SYS_readlink, vec![]),
648         #[cfg(target_arch = "aarch64")]
649         (libc::SYS_readlinkat, vec![]),
650         (libc::SYS_recvfrom, vec![]),
651         (libc::SYS_recvmsg, vec![]),
652         (libc::SYS_restart_syscall, vec![]),
653         // musl is missing this constant
654         // (libc::SYS_rseq, vec![]),
655         #[cfg(target_arch = "x86_64")]
656         (334, vec![]),
657         #[cfg(target_arch = "aarch64")]
658         (293, vec![]),
659         (libc::SYS_rt_sigaction, vec![]),
660         (libc::SYS_rt_sigprocmask, vec![]),
661         (libc::SYS_rt_sigreturn, vec![]),
662         (libc::SYS_sched_getaffinity, vec![]),
663         (libc::SYS_sched_setaffinity, vec![]),
664         (libc::SYS_sched_yield, vec![]),
665         (libc::SYS_seccomp, vec![]),
666         (libc::SYS_sendmsg, vec![]),
667         (libc::SYS_sendto, vec![]),
668         (libc::SYS_set_robust_list, vec![]),
669         (libc::SYS_setsid, vec![]),
670         (libc::SYS_setsockopt, vec![]),
671         (libc::SYS_shutdown, vec![]),
672         (libc::SYS_sigaltstack, vec![]),
673         (
674             libc::SYS_socket,
675             or![
676                 and![Cond::new(0, ArgLen::Dword, Eq, libc::AF_UNIX as u64)?],
677                 and![Cond::new(0, ArgLen::Dword, Eq, libc::AF_INET as u64)?],
678                 and![Cond::new(0, ArgLen::Dword, Eq, libc::AF_INET6 as u64)?],
679             ],
680         ),
681         (libc::SYS_socketpair, vec![]),
682         #[cfg(target_arch = "x86_64")]
683         (libc::SYS_stat, vec![]),
684         (libc::SYS_statfs, vec![]),
685         (libc::SYS_statx, vec![]),
686         (libc::SYS_tgkill, vec![]),
687         (libc::SYS_timerfd_create, vec![]),
688         (libc::SYS_timerfd_settime, vec![]),
689         (libc::SYS_tkill, vec![]),
690         (
691             libc::SYS_umask,
692             or![and![Cond::new(0, ArgLen::Dword, Eq, 0o077)?]],
693         ),
694         #[cfg(target_arch = "x86_64")]
695         (libc::SYS_unlink, vec![]),
696         #[cfg(target_arch = "aarch64")]
697         (libc::SYS_unlinkat, vec![]),
698         (libc::SYS_wait4, vec![]),
699         (libc::SYS_write, vec![]),
700         (libc::SYS_writev, vec![]),
701         (libc::SYS_getcwd, vec![]),
702     ])
703 }
704 
705 #[cfg(feature = "kvm")]
create_vcpu_ioctl_seccomp_rule_kvm() -> Result<Vec<SeccompRule>, BackendError>706 fn create_vcpu_ioctl_seccomp_rule_kvm() -> Result<Vec<SeccompRule>, BackendError> {
707     Ok(or![
708         and![Cond::new(1, ArgLen::Dword, Eq, KVM_CHECK_EXTENSION,)?],
709         and![Cond::new(1, ArgLen::Dword, Eq, KVM_IOEVENTFD)?],
710         and![Cond::new(1, ArgLen::Dword, Eq, KVM_IRQFD,)?],
711         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_DEVICE_ATTR,)?],
712         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_GSI_ROUTING,)?],
713         and![Cond::new(1, ArgLen::Dword, Eq, KVM_SET_USER_MEMORY_REGION,)?],
714         and![Cond::new(1, ArgLen::Dword, Eq, KVM_RUN,)?],
715         and![Cond::new(1, ArgLen::Dword, Eq, KVM_NMI)?],
716     ])
717 }
718 
719 #[cfg(feature = "mshv")]
create_vcpu_ioctl_seccomp_rule_mshv() -> Result<Vec<SeccompRule>, BackendError>720 fn create_vcpu_ioctl_seccomp_rule_mshv() -> Result<Vec<SeccompRule>, BackendError> {
721     Ok(or![
722         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_MSI_ROUTING())?],
723         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_IOEVENTFD())?],
724         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_IRQFD())?],
725         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_RUN_VP())?],
726         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_GET_VP_REGISTERS())?],
727         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_VP_REGISTERS())?],
728         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SET_GUEST_MEMORY())?],
729         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_VP_TRANSLATE_GVA())?],
730         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_GET_VP_CPUID_VALUES())?],
731         and![Cond::new(
732             1,
733             ArgLen::Dword,
734             Eq,
735             MSHV_MODIFY_GPA_HOST_ACCESS()
736         )?],
737         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_READ_GPA())?],
738         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_WRITE_GPA())?],
739         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_SEV_SNP_AP_CREATE())?],
740         and![Cond::new(
741             1,
742             ArgLen::Dword,
743             Eq,
744             MSHV_ISSUE_PSP_GUEST_REQUEST()
745         )?],
746         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_ROOT_HVCALL())?],
747         and![Cond::new(1, ArgLen::Dword, Eq, MSHV_ASSERT_INTERRUPT())?],
748     ])
749 }
750 
create_vcpu_ioctl_seccomp_rule_hypervisor( hypervisor_type: HypervisorType, ) -> Result<Vec<SeccompRule>, BackendError>751 fn create_vcpu_ioctl_seccomp_rule_hypervisor(
752     hypervisor_type: HypervisorType,
753 ) -> Result<Vec<SeccompRule>, BackendError> {
754     match hypervisor_type {
755         #[cfg(feature = "kvm")]
756         HypervisorType::Kvm => create_vcpu_ioctl_seccomp_rule_kvm(),
757         #[cfg(feature = "mshv")]
758         HypervisorType::Mshv => create_vcpu_ioctl_seccomp_rule_mshv(),
759     }
760 }
761 
create_vcpu_ioctl_seccomp_rule( hypervisor_type: HypervisorType, ) -> Result<Vec<SeccompRule>, BackendError>762 fn create_vcpu_ioctl_seccomp_rule(
763     hypervisor_type: HypervisorType,
764 ) -> Result<Vec<SeccompRule>, BackendError> {
765     let mut rules = or![
766         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_DEVICE_SET_IRQS)?],
767         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_GROUP_UNSET_CONTAINER)?],
768         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_IOMMU_MAP_DMA)?],
769         and![Cond::new(1, ArgLen::Dword, Eq, VFIO_IOMMU_UNMAP_DMA)?],
770         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SET_STATUS)?],
771         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_GET_CONFIG)?],
772         and![Cond::new(1, ArgLen::Dword, Eq, VHOST_VDPA_SET_CONFIG)?],
773         and![Cond::new(
774             1,
775             ArgLen::Dword,
776             Eq,
777             VHOST_VDPA_SET_VRING_ENABLE
778         )?],
779     ];
780 
781     let hypervisor_rules = create_vcpu_ioctl_seccomp_rule_hypervisor(hypervisor_type)?;
782 
783     rules.extend(hypervisor_rules);
784 
785     Ok(rules)
786 }
787 
vcpu_thread_rules( hypervisor_type: HypervisorType, ) -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError>788 fn vcpu_thread_rules(
789     hypervisor_type: HypervisorType,
790 ) -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError> {
791     Ok(vec![
792         (libc::SYS_brk, vec![]),
793         (libc::SYS_clock_gettime, vec![]),
794         (libc::SYS_clock_nanosleep, vec![]),
795         (libc::SYS_close, vec![]),
796         (libc::SYS_dup, vec![]),
797         (libc::SYS_exit, vec![]),
798         (libc::SYS_epoll_ctl, vec![]),
799         (libc::SYS_fstat, vec![]),
800         (libc::SYS_futex, vec![]),
801         (libc::SYS_getrandom, vec![]),
802         (libc::SYS_getpid, vec![]),
803         (
804             libc::SYS_ioctl,
805             create_vcpu_ioctl_seccomp_rule(hypervisor_type)?,
806         ),
807         (libc::SYS_lseek, vec![]),
808         (libc::SYS_madvise, vec![]),
809         (libc::SYS_mmap, vec![]),
810         (libc::SYS_mprotect, vec![]),
811         (libc::SYS_mremap, vec![]),
812         (libc::SYS_munmap, vec![]),
813         (libc::SYS_nanosleep, vec![]),
814         (libc::SYS_newfstatat, vec![]),
815         #[cfg(target_arch = "x86_64")]
816         (libc::SYS_open, vec![]),
817         (libc::SYS_openat, vec![]),
818         (libc::SYS_pread64, vec![]),
819         (libc::SYS_pwrite64, vec![]),
820         (libc::SYS_read, vec![]),
821         (libc::SYS_recvfrom, vec![]),
822         (libc::SYS_recvmsg, vec![]),
823         (libc::SYS_rt_sigaction, vec![]),
824         (libc::SYS_rt_sigprocmask, vec![]),
825         (libc::SYS_rt_sigreturn, vec![]),
826         (libc::SYS_sched_yield, vec![]),
827         (libc::SYS_sendmsg, vec![]),
828         (libc::SYS_shutdown, vec![]),
829         (libc::SYS_sigaltstack, vec![]),
830         (libc::SYS_tgkill, vec![]),
831         (libc::SYS_tkill, vec![]),
832         #[cfg(target_arch = "x86_64")]
833         (libc::SYS_unlink, vec![]),
834         #[cfg(target_arch = "aarch64")]
835         (libc::SYS_unlinkat, vec![]),
836         (libc::SYS_write, vec![]),
837         (libc::SYS_writev, vec![]),
838         #[cfg(debug_assertions)]
839         (libc::SYS_fcntl, vec![]),
840         (libc::SYS_getcwd, vec![]),
841     ])
842 }
843 
844 // The filter containing the white listed syscall rules required by the HTTP API to
845 // function.
http_api_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError>846 fn http_api_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError> {
847     Ok(vec![
848         (libc::SYS_accept4, vec![]),
849         (libc::SYS_brk, vec![]),
850         (libc::SYS_clock_gettime, vec![]),
851         (libc::SYS_close, vec![]),
852         (libc::SYS_dup, vec![]),
853         (libc::SYS_epoll_create1, vec![]),
854         (libc::SYS_epoll_ctl, vec![]),
855         (libc::SYS_epoll_pwait, vec![]),
856         #[cfg(target_arch = "x86_64")]
857         (libc::SYS_epoll_wait, vec![]),
858         (libc::SYS_exit, vec![]),
859         (libc::SYS_fcntl, vec![]),
860         (libc::SYS_futex, vec![]),
861         (libc::SYS_getrandom, vec![]),
862         (libc::SYS_ioctl, create_api_ioctl_seccomp_rule()?),
863         (libc::SYS_landlock_create_ruleset, vec![]),
864         (libc::SYS_landlock_restrict_self, vec![]),
865         (libc::SYS_madvise, vec![]),
866         (libc::SYS_mmap, vec![]),
867         (libc::SYS_mprotect, vec![]),
868         (libc::SYS_munmap, vec![]),
869         (libc::SYS_prctl, vec![]),
870         (libc::SYS_recvfrom, vec![]),
871         (libc::SYS_recvmsg, vec![]),
872         (libc::SYS_sched_yield, vec![]),
873         (libc::SYS_sigaltstack, vec![]),
874         (libc::SYS_write, vec![]),
875         (libc::SYS_rt_sigprocmask, vec![]),
876         (libc::SYS_getcwd, vec![]),
877     ])
878 }
879 
880 // The filter containing the white listed syscall rules required by the D-Bus API
881 // to function.
882 #[cfg(feature = "dbus_api")]
dbus_api_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError>883 fn dbus_api_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError> {
884     Ok(vec![
885         (libc::SYS_brk, vec![]),
886         (libc::SYS_clock_gettime, vec![]),
887         (libc::SYS_clone, vec![]),
888         (libc::SYS_clone3, vec![]),
889         (libc::SYS_close, vec![]),
890         (libc::SYS_dup, vec![]),
891         (libc::SYS_epoll_ctl, vec![]),
892         (libc::SYS_exit, vec![]),
893         (libc::SYS_futex, vec![]),
894         (libc::SYS_getrandom, vec![]),
895         (libc::SYS_madvise, vec![]),
896         (libc::SYS_mmap, vec![]),
897         (libc::SYS_mprotect, vec![]),
898         (libc::SYS_munmap, vec![]),
899         (libc::SYS_prctl, vec![]),
900         (libc::SYS_recvmsg, vec![]),
901         // musl is missing this constant
902         // (libc::SYS_rseq, vec![]),
903         #[cfg(target_arch = "x86_64")]
904         (334, vec![]),
905         #[cfg(target_arch = "aarch64")]
906         (293, vec![]),
907         (libc::SYS_rt_sigprocmask, vec![]),
908         (libc::SYS_sched_getaffinity, vec![]),
909         (libc::SYS_sched_yield, vec![]),
910         (libc::SYS_sendmsg, vec![]),
911         (libc::SYS_set_robust_list, vec![]),
912         (libc::SYS_sigaltstack, vec![]),
913         (libc::SYS_write, vec![]),
914         (libc::SYS_getcwd, vec![]),
915     ])
916 }
917 
event_monitor_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError>918 fn event_monitor_thread_rules() -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError> {
919     Ok(vec![
920         (libc::SYS_brk, vec![]),
921         (libc::SYS_close, vec![]),
922         (libc::SYS_futex, vec![]),
923         (libc::SYS_landlock_create_ruleset, vec![]),
924         (libc::SYS_landlock_restrict_self, vec![]),
925         (libc::SYS_mmap, vec![]),
926         (libc::SYS_munmap, vec![]),
927         (libc::SYS_prctl, vec![]),
928         (libc::SYS_sched_yield, vec![]),
929         (libc::SYS_write, vec![]),
930         (libc::SYS_getcwd, vec![]),
931     ])
932 }
933 
get_seccomp_rules( thread_type: Thread, hypervisor_type: HypervisorType, ) -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError>934 fn get_seccomp_rules(
935     thread_type: Thread,
936     hypervisor_type: HypervisorType,
937 ) -> Result<Vec<(i64, Vec<SeccompRule>)>, BackendError> {
938     match thread_type {
939         Thread::HttpApi => Ok(http_api_thread_rules()?),
940         #[cfg(feature = "dbus_api")]
941         Thread::DBusApi => Ok(dbus_api_thread_rules()?),
942         Thread::EventMonitor => Ok(event_monitor_thread_rules()?),
943         Thread::SignalHandler => Ok(signal_handler_thread_rules()?),
944         Thread::Vcpu => Ok(vcpu_thread_rules(hypervisor_type)?),
945         Thread::Vmm => Ok(vmm_thread_rules(hypervisor_type)?),
946         Thread::PtyForeground => Ok(pty_foreground_thread_rules()?),
947     }
948 }
949 
950 /// Generate a BPF program based on the seccomp_action value
get_seccomp_filter( seccomp_action: &SeccompAction, thread_type: Thread, hypervisor_type: HypervisorType, ) -> Result<BpfProgram, Error>951 pub fn get_seccomp_filter(
952     seccomp_action: &SeccompAction,
953     thread_type: Thread,
954     hypervisor_type: HypervisorType,
955 ) -> Result<BpfProgram, Error> {
956     match seccomp_action {
957         SeccompAction::Allow => Ok(vec![]),
958         SeccompAction::Log => SeccompFilter::new(
959             get_seccomp_rules(thread_type, hypervisor_type)
960                 .map_err(Error::Backend)?
961                 .into_iter()
962                 .collect(),
963             SeccompAction::Log,
964             SeccompAction::Allow,
965             std::env::consts::ARCH.try_into().unwrap(),
966         )
967         .and_then(|filter| filter.try_into())
968         .map_err(Error::Backend),
969         _ => SeccompFilter::new(
970             get_seccomp_rules(thread_type, hypervisor_type)
971                 .map_err(Error::Backend)?
972                 .into_iter()
973                 .collect(),
974             SeccompAction::Trap,
975             SeccompAction::Allow,
976             std::env::consts::ARCH.try_into().unwrap(),
977         )
978         .and_then(|filter| filter.try_into())
979         .map_err(Error::Backend),
980     }
981 }
982