1use caps::{Capability as CapsCapability, *};
3use oci_spec::runtime::{Capabilities, Capability as SpecCapability, LinuxCapabilities};
4
5use crate::syscall::{Syscall, SyscallError};
6
7fn to_set(caps: &Capabilities) -> CapsHashSet {
9 let mut capabilities = CapsHashSet::new();
10
11 for c in caps {
12 let cap = c.to_cap();
13 capabilities.insert(cap);
14 }
15 capabilities
16}
17
18pub trait CapabilityExt {
19 fn to_cap(&self) -> caps::Capability;
21 fn from_cap(c: CapsCapability) -> Self;
23}
24
25impl CapabilityExt for SpecCapability {
26 fn to_cap(&self) -> caps::Capability {
28 match self {
29 SpecCapability::AuditControl => CapsCapability::CAP_AUDIT_CONTROL,
30 SpecCapability::AuditRead => CapsCapability::CAP_AUDIT_READ,
31 SpecCapability::AuditWrite => CapsCapability::CAP_AUDIT_WRITE,
32 SpecCapability::BlockSuspend => CapsCapability::CAP_BLOCK_SUSPEND,
33 SpecCapability::Bpf => CapsCapability::CAP_BPF,
34 SpecCapability::CheckpointRestore => CapsCapability::CAP_CHECKPOINT_RESTORE,
35 SpecCapability::Chown => CapsCapability::CAP_CHOWN,
36 SpecCapability::DacOverride => CapsCapability::CAP_DAC_OVERRIDE,
37 SpecCapability::DacReadSearch => CapsCapability::CAP_DAC_READ_SEARCH,
38 SpecCapability::Fowner => CapsCapability::CAP_FOWNER,
39 SpecCapability::Fsetid => CapsCapability::CAP_FSETID,
40 SpecCapability::IpcLock => CapsCapability::CAP_IPC_LOCK,
41 SpecCapability::IpcOwner => CapsCapability::CAP_IPC_OWNER,
42 SpecCapability::Kill => CapsCapability::CAP_KILL,
43 SpecCapability::Lease => CapsCapability::CAP_LEASE,
44 SpecCapability::LinuxImmutable => CapsCapability::CAP_LINUX_IMMUTABLE,
45 SpecCapability::MacAdmin => CapsCapability::CAP_MAC_ADMIN,
46 SpecCapability::MacOverride => CapsCapability::CAP_MAC_OVERRIDE,
47 SpecCapability::Mknod => CapsCapability::CAP_MKNOD,
48 SpecCapability::NetAdmin => CapsCapability::CAP_NET_ADMIN,
49 SpecCapability::NetBindService => CapsCapability::CAP_NET_BIND_SERVICE,
50 SpecCapability::NetBroadcast => CapsCapability::CAP_NET_BROADCAST,
51 SpecCapability::NetRaw => CapsCapability::CAP_NET_RAW,
52 SpecCapability::Perfmon => CapsCapability::CAP_PERFMON,
53 SpecCapability::Setgid => CapsCapability::CAP_SETGID,
54 SpecCapability::Setfcap => CapsCapability::CAP_SETFCAP,
55 SpecCapability::Setpcap => CapsCapability::CAP_SETPCAP,
56 SpecCapability::Setuid => CapsCapability::CAP_SETUID,
57 SpecCapability::SysAdmin => CapsCapability::CAP_SYS_ADMIN,
58 SpecCapability::SysBoot => CapsCapability::CAP_SYS_BOOT,
59 SpecCapability::SysChroot => CapsCapability::CAP_SYS_CHROOT,
60 SpecCapability::SysModule => CapsCapability::CAP_SYS_MODULE,
61 SpecCapability::SysNice => CapsCapability::CAP_SYS_NICE,
62 SpecCapability::SysPacct => CapsCapability::CAP_SYS_PACCT,
63 SpecCapability::SysPtrace => CapsCapability::CAP_SYS_PTRACE,
64 SpecCapability::SysRawio => CapsCapability::CAP_SYS_RAWIO,
65 SpecCapability::SysResource => CapsCapability::CAP_SYS_RESOURCE,
66 SpecCapability::SysTime => CapsCapability::CAP_SYS_TIME,
67 SpecCapability::SysTtyConfig => CapsCapability::CAP_SYS_TTY_CONFIG,
68 SpecCapability::Syslog => CapsCapability::CAP_SYSLOG,
69 SpecCapability::WakeAlarm => CapsCapability::CAP_WAKE_ALARM,
70 }
71 }
72
73 fn from_cap(c: CapsCapability) -> SpecCapability {
75 match c {
76 CapsCapability::CAP_AUDIT_CONTROL => SpecCapability::AuditControl,
77 CapsCapability::CAP_AUDIT_READ => SpecCapability::AuditRead,
78 CapsCapability::CAP_AUDIT_WRITE => SpecCapability::AuditWrite,
79 CapsCapability::CAP_BLOCK_SUSPEND => SpecCapability::BlockSuspend,
80 CapsCapability::CAP_BPF => SpecCapability::Bpf,
81 CapsCapability::CAP_CHECKPOINT_RESTORE => SpecCapability::CheckpointRestore,
82 CapsCapability::CAP_CHOWN => SpecCapability::Chown,
83 CapsCapability::CAP_DAC_OVERRIDE => SpecCapability::DacOverride,
84 CapsCapability::CAP_DAC_READ_SEARCH => SpecCapability::DacReadSearch,
85 CapsCapability::CAP_FOWNER => SpecCapability::Fowner,
86 CapsCapability::CAP_FSETID => SpecCapability::Fsetid,
87 CapsCapability::CAP_IPC_LOCK => SpecCapability::IpcLock,
88 CapsCapability::CAP_IPC_OWNER => SpecCapability::IpcOwner,
89 CapsCapability::CAP_KILL => SpecCapability::Kill,
90 CapsCapability::CAP_LEASE => SpecCapability::Lease,
91 CapsCapability::CAP_LINUX_IMMUTABLE => SpecCapability::LinuxImmutable,
92 CapsCapability::CAP_MAC_ADMIN => SpecCapability::MacAdmin,
93 CapsCapability::CAP_MAC_OVERRIDE => SpecCapability::MacOverride,
94 CapsCapability::CAP_MKNOD => SpecCapability::Mknod,
95 CapsCapability::CAP_NET_ADMIN => SpecCapability::NetAdmin,
96 CapsCapability::CAP_NET_BIND_SERVICE => SpecCapability::NetBindService,
97 CapsCapability::CAP_NET_BROADCAST => SpecCapability::NetBroadcast,
98 CapsCapability::CAP_NET_RAW => SpecCapability::NetRaw,
99 CapsCapability::CAP_PERFMON => SpecCapability::Perfmon,
100 CapsCapability::CAP_SETGID => SpecCapability::Setgid,
101 CapsCapability::CAP_SETFCAP => SpecCapability::Setfcap,
102 CapsCapability::CAP_SETPCAP => SpecCapability::Setpcap,
103 CapsCapability::CAP_SETUID => SpecCapability::Setuid,
104 CapsCapability::CAP_SYS_ADMIN => SpecCapability::SysAdmin,
105 CapsCapability::CAP_SYS_BOOT => SpecCapability::SysBoot,
106 CapsCapability::CAP_SYS_CHROOT => SpecCapability::SysChroot,
107 CapsCapability::CAP_SYS_MODULE => SpecCapability::SysModule,
108 CapsCapability::CAP_SYS_NICE => SpecCapability::SysNice,
109 CapsCapability::CAP_SYS_PACCT => SpecCapability::SysPacct,
110 CapsCapability::CAP_SYS_PTRACE => SpecCapability::SysPtrace,
111 CapsCapability::CAP_SYS_RAWIO => SpecCapability::SysRawio,
112 CapsCapability::CAP_SYS_RESOURCE => SpecCapability::SysResource,
113 CapsCapability::CAP_SYS_TIME => SpecCapability::SysTime,
114 CapsCapability::CAP_SYS_TTY_CONFIG => SpecCapability::SysTtyConfig,
115 CapsCapability::CAP_SYSLOG => SpecCapability::Syslog,
116 CapsCapability::CAP_WAKE_ALARM => SpecCapability::WakeAlarm,
117 CapsCapability::__Nonexhaustive => unreachable!("invalid capability"),
118 }
119 }
120}
121
122pub fn reset_effective<S: Syscall + ?Sized>(syscall: &S) -> Result<(), SyscallError> {
126 tracing::debug!("reset all caps");
127 let permitted = caps::read(None, CapSet::Permitted)?;
129 syscall.set_capability(CapSet::Effective, &permitted)?;
130 Ok(())
131}
132
133pub fn drop_privileges<S: Syscall + ?Sized>(
135 cs: &LinuxCapabilities,
136 syscall: &S,
137) -> Result<(), SyscallError> {
138 if let Some(bounding) = cs.bounding() {
139 tracing::debug!("dropping bounding capabilities to {:?}", bounding);
140 syscall.set_capability(CapSet::Bounding, &to_set(bounding))?;
141 }
142
143 if let Some(effective) = cs.effective() {
144 tracing::debug!("dropping effective capabilities to {:?}", effective);
145 syscall.set_capability(CapSet::Effective, &to_set(effective))?;
146 }
147
148 if let Some(permitted) = cs.permitted() {
149 tracing::debug!("dropping permitted capabilities to {:?}", permitted);
150 syscall.set_capability(CapSet::Permitted, &to_set(permitted))?;
151 }
152
153 if let Some(inheritable) = cs.inheritable() {
154 tracing::debug!("dropping inheritable capabilities to {:?}", inheritable);
155 syscall.set_capability(CapSet::Inheritable, &to_set(inheritable))?;
156 }
157
158 if let Some(ambient) = cs.ambient() {
159 tracing::debug!("dropping ambient capabilities to {:?}", ambient);
160 syscall.set_capability(CapSet::Ambient, &to_set(ambient))?;
161 }
162
163 Ok(())
164}
165
166#[cfg(test)]
167mod tests {
168 use std::collections::HashSet;
169
170 use oci_spec::runtime::LinuxCapabilitiesBuilder;
171
172 use super::*;
173 use crate::syscall::test::TestHelperSyscall;
174
175 #[test]
176 fn test_reset_effective() {
177 let test_command = TestHelperSyscall::default();
178 let permitted_caps = caps::read(None, CapSet::Permitted).unwrap();
179 assert!(reset_effective(&test_command).is_ok());
180 let set_capability_args: Vec<_> = test_command
181 .get_set_capability_args()
182 .into_iter()
183 .map(|(_capset, caps)| caps)
184 .collect();
185 assert_eq!(set_capability_args, vec![permitted_caps]);
186 }
187
188 #[test]
189 fn test_convert_oci_spec_to_caps_type() {
190 struct Testcase {
191 input: SpecCapability,
192 want: CapsCapability,
193 }
194
195 let tests = vec![
196 Testcase {
197 input: SpecCapability::AuditControl,
198 want: CapsCapability::CAP_AUDIT_CONTROL,
199 },
200 Testcase {
201 input: SpecCapability::AuditRead,
202 want: CapsCapability::CAP_AUDIT_READ,
203 },
204 Testcase {
205 input: SpecCapability::AuditWrite,
206 want: CapsCapability::CAP_AUDIT_WRITE,
207 },
208 Testcase {
209 input: SpecCapability::BlockSuspend,
210 want: CapsCapability::CAP_BLOCK_SUSPEND,
211 },
212 Testcase {
213 input: SpecCapability::Bpf,
214 want: CapsCapability::CAP_BPF,
215 },
216 Testcase {
217 input: SpecCapability::CheckpointRestore,
218 want: CapsCapability::CAP_CHECKPOINT_RESTORE,
219 },
220 Testcase {
221 input: SpecCapability::Chown,
222 want: Capability::CAP_CHOWN,
223 },
224 Testcase {
225 input: SpecCapability::DacOverride,
226 want: CapsCapability::CAP_DAC_OVERRIDE,
227 },
228 Testcase {
229 input: SpecCapability::DacReadSearch,
230 want: CapsCapability::CAP_DAC_READ_SEARCH,
231 },
232 Testcase {
233 input: SpecCapability::Fowner,
234 want: CapsCapability::CAP_FOWNER,
235 },
236 Testcase {
237 input: SpecCapability::Fsetid,
238 want: CapsCapability::CAP_FSETID,
239 },
240 Testcase {
241 input: SpecCapability::IpcLock,
242 want: CapsCapability::CAP_IPC_LOCK,
243 },
244 Testcase {
245 input: SpecCapability::IpcOwner,
246 want: CapsCapability::CAP_IPC_OWNER,
247 },
248 Testcase {
249 input: SpecCapability::Kill,
250 want: CapsCapability::CAP_KILL,
251 },
252 Testcase {
253 input: SpecCapability::Lease,
254 want: CapsCapability::CAP_LEASE,
255 },
256 Testcase {
257 input: SpecCapability::LinuxImmutable,
258 want: CapsCapability::CAP_LINUX_IMMUTABLE,
259 },
260 Testcase {
261 input: SpecCapability::MacAdmin,
262 want: CapsCapability::CAP_MAC_ADMIN,
263 },
264 Testcase {
265 input: SpecCapability::MacOverride,
266 want: CapsCapability::CAP_MAC_OVERRIDE,
267 },
268 Testcase {
269 input: SpecCapability::Mknod,
270 want: CapsCapability::CAP_MKNOD,
271 },
272 Testcase {
273 input: SpecCapability::NetAdmin,
274 want: CapsCapability::CAP_NET_ADMIN,
275 },
276 Testcase {
277 input: SpecCapability::NetBindService,
278 want: CapsCapability::CAP_NET_BIND_SERVICE,
279 },
280 Testcase {
281 input: SpecCapability::NetBroadcast,
282 want: CapsCapability::CAP_NET_BROADCAST,
283 },
284 Testcase {
285 input: SpecCapability::NetRaw,
286 want: CapsCapability::CAP_NET_RAW,
287 },
288 Testcase {
289 input: SpecCapability::Perfmon,
290 want: CapsCapability::CAP_PERFMON,
291 },
292 Testcase {
293 input: SpecCapability::Setgid,
294 want: CapsCapability::CAP_SETGID,
295 },
296 Testcase {
297 input: SpecCapability::Setfcap,
298 want: CapsCapability::CAP_SETFCAP,
299 },
300 Testcase {
301 input: SpecCapability::Setpcap,
302 want: CapsCapability::CAP_SETPCAP,
303 },
304 Testcase {
305 input: SpecCapability::Setuid,
306 want: CapsCapability::CAP_SETUID,
307 },
308 Testcase {
309 input: SpecCapability::SysAdmin,
310 want: CapsCapability::CAP_SYS_ADMIN,
311 },
312 Testcase {
313 input: SpecCapability::SysBoot,
314 want: CapsCapability::CAP_SYS_BOOT,
315 },
316 Testcase {
317 input: SpecCapability::SysChroot,
318 want: CapsCapability::CAP_SYS_CHROOT,
319 },
320 Testcase {
321 input: SpecCapability::SysModule,
322 want: CapsCapability::CAP_SYS_MODULE,
323 },
324 Testcase {
325 input: SpecCapability::SysNice,
326 want: CapsCapability::CAP_SYS_NICE,
327 },
328 Testcase {
329 input: SpecCapability::SysPacct,
330 want: CapsCapability::CAP_SYS_PACCT,
331 },
332 Testcase {
333 input: SpecCapability::SysPtrace,
334 want: CapsCapability::CAP_SYS_PTRACE,
335 },
336 Testcase {
337 input: SpecCapability::SysRawio,
338 want: CapsCapability::CAP_SYS_RAWIO,
339 },
340 Testcase {
341 input: SpecCapability::SysResource,
342 want: CapsCapability::CAP_SYS_RESOURCE,
343 },
344 Testcase {
345 input: SpecCapability::SysTime,
346 want: CapsCapability::CAP_SYS_TIME,
347 },
348 Testcase {
349 input: SpecCapability::SysTtyConfig,
350 want: CapsCapability::CAP_SYS_TTY_CONFIG,
351 },
352 Testcase {
353 input: SpecCapability::Syslog,
354 want: CapsCapability::CAP_SYSLOG,
355 },
356 Testcase {
357 input: SpecCapability::WakeAlarm,
358 want: CapsCapability::CAP_WAKE_ALARM,
359 },
360 ];
361
362 for test in tests {
363 let got = test.input.to_cap();
364 assert_eq!(got, test.want);
365 }
366 }
367
368 #[test]
369 fn test_convert_caps_type_to_oci_spec() {
370 struct Testcase {
371 input: CapsCapability,
372 want: SpecCapability,
373 }
374
375 let tests = vec![
376 Testcase {
377 input: CapsCapability::CAP_AUDIT_CONTROL,
378 want: SpecCapability::AuditControl,
379 },
380 Testcase {
381 input: CapsCapability::CAP_AUDIT_READ,
382 want: SpecCapability::AuditRead,
383 },
384 Testcase {
385 input: CapsCapability::CAP_AUDIT_WRITE,
386 want: SpecCapability::AuditWrite,
387 },
388 Testcase {
389 input: CapsCapability::CAP_BLOCK_SUSPEND,
390 want: SpecCapability::BlockSuspend,
391 },
392 Testcase {
393 input: CapsCapability::CAP_BPF,
394 want: SpecCapability::Bpf,
395 },
396 Testcase {
397 input: CapsCapability::CAP_CHECKPOINT_RESTORE,
398 want: SpecCapability::CheckpointRestore,
399 },
400 Testcase {
401 input: CapsCapability::CAP_CHOWN,
402 want: SpecCapability::Chown,
403 },
404 Testcase {
405 input: CapsCapability::CAP_DAC_OVERRIDE,
406 want: SpecCapability::DacOverride,
407 },
408 Testcase {
409 input: CapsCapability::CAP_DAC_READ_SEARCH,
410 want: SpecCapability::DacReadSearch,
411 },
412 Testcase {
413 input: CapsCapability::CAP_FOWNER,
414 want: SpecCapability::Fowner,
415 },
416 Testcase {
417 input: CapsCapability::CAP_FSETID,
418 want: SpecCapability::Fsetid,
419 },
420 Testcase {
421 input: CapsCapability::CAP_IPC_LOCK,
422 want: SpecCapability::IpcLock,
423 },
424 Testcase {
425 input: CapsCapability::CAP_IPC_OWNER,
426 want: SpecCapability::IpcOwner,
427 },
428 Testcase {
429 input: CapsCapability::CAP_KILL,
430 want: SpecCapability::Kill,
431 },
432 Testcase {
433 input: CapsCapability::CAP_LEASE,
434 want: SpecCapability::Lease,
435 },
436 Testcase {
437 input: CapsCapability::CAP_LINUX_IMMUTABLE,
438 want: SpecCapability::LinuxImmutable,
439 },
440 Testcase {
441 input: CapsCapability::CAP_MAC_ADMIN,
442 want: SpecCapability::MacAdmin,
443 },
444 Testcase {
445 input: CapsCapability::CAP_MAC_OVERRIDE,
446 want: SpecCapability::MacOverride,
447 },
448 Testcase {
449 input: CapsCapability::CAP_MKNOD,
450 want: SpecCapability::Mknod,
451 },
452 Testcase {
453 input: CapsCapability::CAP_NET_ADMIN,
454 want: SpecCapability::NetAdmin,
455 },
456 Testcase {
457 input: CapsCapability::CAP_NET_BIND_SERVICE,
458 want: SpecCapability::NetBindService,
459 },
460 Testcase {
461 input: CapsCapability::CAP_NET_BROADCAST,
462 want: SpecCapability::NetBroadcast,
463 },
464 Testcase {
465 input: CapsCapability::CAP_NET_RAW,
466 want: SpecCapability::NetRaw,
467 },
468 Testcase {
469 input: CapsCapability::CAP_PERFMON,
470 want: SpecCapability::Perfmon,
471 },
472 Testcase {
473 input: CapsCapability::CAP_SETGID,
474 want: SpecCapability::Setgid,
475 },
476 Testcase {
477 input: CapsCapability::CAP_SETFCAP,
478 want: SpecCapability::Setfcap,
479 },
480 Testcase {
481 input: CapsCapability::CAP_SETPCAP,
482 want: SpecCapability::Setpcap,
483 },
484 Testcase {
485 input: CapsCapability::CAP_SETUID,
486 want: SpecCapability::Setuid,
487 },
488 Testcase {
489 input: CapsCapability::CAP_SYS_ADMIN,
490 want: SpecCapability::SysAdmin,
491 },
492 Testcase {
493 input: CapsCapability::CAP_SYS_BOOT,
494 want: SpecCapability::SysBoot,
495 },
496 Testcase {
497 input: CapsCapability::CAP_SYS_CHROOT,
498 want: SpecCapability::SysChroot,
499 },
500 Testcase {
501 input: CapsCapability::CAP_SYS_MODULE,
502 want: SpecCapability::SysModule,
503 },
504 Testcase {
505 input: CapsCapability::CAP_SYS_NICE,
506 want: SpecCapability::SysNice,
507 },
508 Testcase {
509 input: CapsCapability::CAP_SYS_PACCT,
510 want: SpecCapability::SysPacct,
511 },
512 Testcase {
513 input: CapsCapability::CAP_SYS_PTRACE,
514 want: SpecCapability::SysPtrace,
515 },
516 Testcase {
517 input: CapsCapability::CAP_SYS_RAWIO,
518 want: SpecCapability::SysRawio,
519 },
520 Testcase {
521 input: CapsCapability::CAP_SYS_RESOURCE,
522 want: SpecCapability::SysResource,
523 },
524 Testcase {
525 input: CapsCapability::CAP_SYS_TIME,
526 want: SpecCapability::SysTime,
527 },
528 Testcase {
529 input: CapsCapability::CAP_SYS_TTY_CONFIG,
530 want: SpecCapability::SysTtyConfig,
531 },
532 Testcase {
533 input: CapsCapability::CAP_SYSLOG,
534 want: SpecCapability::Syslog,
535 },
536 Testcase {
537 input: CapsCapability::CAP_WAKE_ALARM,
538 want: SpecCapability::WakeAlarm,
539 },
540 ];
541
542 for test in tests {
543 let got = SpecCapability::from_cap(test.input);
544 assert_eq!(got, test.want);
545 }
546 }
547
548 #[test]
549 fn test_drop_privileges() {
550 struct Testcase {
551 name: String,
552 input: LinuxCapabilities,
553 want: Vec<(CapSet, Vec<SpecCapability>)>,
556 }
557
558 let cps = vec![
559 SpecCapability::AuditWrite,
560 SpecCapability::Kill,
561 SpecCapability::NetBindService,
562 ];
563
564 let tests = vec![
565 Testcase {
566 name: format!("all LinuxCapabilities fields with caps: {cps:?}"),
567 input: LinuxCapabilitiesBuilder::default()
568 .bounding(cps.clone().into_iter().collect::<Capabilities>())
569 .effective(cps.clone().into_iter().collect::<Capabilities>())
570 .inheritable(cps.clone().into_iter().collect::<Capabilities>())
571 .permitted(cps.clone().into_iter().collect::<Capabilities>())
572 .ambient(cps.clone().into_iter().collect::<Capabilities>())
573 .build()
574 .unwrap(),
575 want: vec![
576 (CapSet::Bounding, cps.clone()),
577 (CapSet::Effective, cps.clone()),
578 (CapSet::Permitted, cps.clone()),
579 (CapSet::Inheritable, cps.clone()),
580 (CapSet::Ambient, cps.clone()),
581 ],
582 },
583 Testcase {
584 name: format!("partial LinuxCapabilities fields with caps: {cps:?}"),
585 input: LinuxCapabilitiesBuilder::default()
586 .bounding(cps.clone().into_iter().collect::<Capabilities>())
587 .effective(cps.clone().into_iter().collect::<Capabilities>())
588 .permitted(cps.clone().into_iter().collect::<Capabilities>())
589 .build()
590 .unwrap(),
591 want: vec![
592 (CapSet::Bounding, cps.clone()),
593 (CapSet::Effective, cps.clone()),
594 (CapSet::Permitted, cps.clone()),
595 (CapSet::Inheritable, cps.clone()),
596 (CapSet::Ambient, cps.clone()),
597 ],
598 },
599 Testcase {
600 name: format!("empty LinuxCapabilities fields with caps: {cps:?}"),
601 input: LinuxCapabilitiesBuilder::default()
602 .bounding(HashSet::new())
603 .effective(HashSet::new())
604 .inheritable(HashSet::new())
605 .permitted(HashSet::new())
606 .ambient(HashSet::new())
607 .build()
608 .unwrap(),
609 want: vec![
610 (CapSet::Bounding, cps.clone()),
611 (CapSet::Effective, cps.clone()),
612 (CapSet::Permitted, cps.clone()),
613 (CapSet::Inheritable, cps.clone()),
614 (CapSet::Ambient, cps),
615 ],
616 },
617 ];
618
619 for test in tests {
620 let test_command = TestHelperSyscall::default();
621 assert!(
622 drop_privileges(&test.input, &test_command).is_ok(),
623 "{}, drop_privileges is not ok",
624 test.name
625 );
626
627 let got: Vec<(CapSet, Vec<_>)> = test_command
628 .get_set_capability_args()
629 .into_iter()
630 .map(|(capset, caps)| {
631 (
632 capset,
633 caps.into_iter().map(SpecCapability::from_cap).collect(),
634 )
635 })
636 .collect();
637 assert_eq!(
638 got.len(),
639 test.want.len(),
640 "{}, len of got:{}, want:{}",
641 test.name,
642 got.len(),
643 test.want.len(),
644 );
645
646 for (i, want) in test.want.iter().enumerate().take(test.want.len()) {
647 let want_cap_set = format!("{:?}", want.0);
650 let got_cap_set = format!("{:?}", got[i].0);
651 let want_caps = &want.1;
652 let got_caps = &got[i].1;
653
654 assert_eq!(
655 got_cap_set, want_cap_set,
656 "{}, capset of got:{}, want:{}",
657 test.name, got_cap_set, want_cap_set,
658 );
659 assert!(
662 got_caps.iter().all(|cap| want_caps.contains(cap)),
663 "{}, caps of got:{:?}, want:{:?}",
664 test.name,
665 got_caps,
666 want_caps
667 );
668 }
669 }
670 }
671}