1#![doc = include_str!("../README.md")]
2
3use std::{error, fmt};
4pub mod action;
5pub mod attribute;
6pub mod filter;
7pub mod notify;
8pub mod raw;
9pub mod syscall;
10
11pub fn get_architecture() -> u32 {
13 unsafe { raw::seccomp_arch_native() }
14}
15
16#[derive(Debug)]
18pub enum Error {
19 Filter(filter::Error),
21
22 Syscall(syscall::Error),
24
25 #[cfg(feature = "notify")]
27 Notify(notify::Error),
28}
29impl fmt::Display for Error {
30 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 match self {
32 Self::Filter(e) => write!(f, "Filter Error: {e}"),
33 Self::Syscall(e) => write!(f, "Syscall Error: {e}"),
34
35 #[cfg(feature = "notify")]
36 Self::Notify(e) => write!(f, "Notify Error: {e}"),
37 }
38 }
39}
40impl error::Error for Error {
41 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
42 match self {
43 Error::Filter(e) => Some(e),
44 Error::Syscall(e) => Some(e),
45
46 #[cfg(feature = "notify")]
47 Error::Notify(e) => Some(e),
48 }
49 }
50}
51impl From<filter::Error> for Error {
52 fn from(e: filter::Error) -> Self {
53 Self::Filter(e)
54 }
55}
56impl From<syscall::Error> for Error {
57 fn from(e: syscall::Error) -> Self {
58 Self::Syscall(e)
59 }
60}
61
62#[cfg(feature = "notify")]
63impl From<notify::Error> for Error {
64 fn from(e: notify::Error) -> Self {
65 Self::Notify(e)
66 }
67}
68
69#[cfg(test)]
70mod tests {
71 use crate::{
72 action::Action,
73 attribute::{Attribute, OptimizeStrategy},
74 filter::Filter,
75 syscall::Syscall,
76 };
77
78 #[test]
79 fn init_and_release() {
80 Filter::new(Action::Allow).expect("Allow Default Failed");
81 Filter::new(Action::KillProcess).expect("KillProcess Default Failed");
82 Filter::new(Action::KillThread).expect("KillThread Default Failed");
83 Filter::new(Action::Log).expect("Log Default Failed");
84 Filter::new(Action::Trap).expect("Trap Default Failed");
85 }
86
87 #[test]
88 fn attributes() {
89 let mut filter = Filter::new(Action::Log).expect("Log Default Failed");
90
91 filter
92 .set_attribute(Attribute::BadArchAction(Action::KillProcess))
93 .expect("Failed to set Default Action");
94
95 filter
96 .set_attribute(Attribute::DisableSSB(true))
97 .expect("Failed to disable SSB");
98
99 filter
100 .set_attribute(Attribute::Log(true))
101 .expect("Failed to set Log");
102
103 filter
104 .set_attribute(Attribute::NoNewPrivileges(true))
105 .expect("Failed to set NoNewPrivileges");
106
107 filter
108 .set_attribute(Attribute::Optimize(OptimizeStrategy::BinaryTree))
109 .expect("Failed to set Optimization Type to BST");
110
111 filter
112 .set_attribute(Attribute::Optimize(OptimizeStrategy::PriorityAndComplexity))
113 .expect("Failed to set Optimization Type to default");
114
115 filter
116 .set_attribute(Attribute::ReturnSystemReturnCodes(true))
117 .expect("Failed to set SysRawRC");
118
119 filter
120 .set_attribute(Attribute::NegativeSyscalls(true))
121 .expect("Failed to set TSkip");
122
123 filter
124 .set_attribute(Attribute::ThreadSync(true))
125 .expect("Failed to set ThreadSync");
126 }
127
128 #[test]
129 fn add_rule() {
130 let mut filter = Filter::new(Action::Allow).expect("Failed to create filter");
131 filter
132 .add_rule(
133 Action::Allow,
134 Syscall::from_name("read").expect("Failed to get read syscall"),
135 )
136 .expect_err("libseccomp should not allow a rule that is the default");
137 filter
138 .add_rule(
139 Action::KillProcess,
140 Syscall::from_name("execve").expect("Failed to get ptrace syscall"),
141 )
142 .expect("Failed to kill execve");
143 filter
144 .add_rule(Action::KillThread, Syscall::from_number(1))
145 .expect("Failed to kill syscall 1");
146 filter
147 .add_rule(Action::Log, Syscall::from_number(2))
148 .expect("Failed to log syscall 2");
149 filter
150 .add_rule(Action::Trap, Syscall::from_number(3))
151 .expect("Failed to log syscall 3");
152 }
153}