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