1use seccomp_sys::*;
2
3use sandbox::syscalls::Syscall;
4
5mod errors {
6 error_chain! {
7 errors {
8 FFI
9 }
10 }
11}
12pub use self::errors::{Result, Error, ErrorKind};
13
14
15pub struct Context {
16 ctx: *mut scmp_filter_ctx,
17}
18
19impl Context {
20 fn init() -> Result<Context> {
21 let ctx = unsafe { seccomp_init(SCMP_ACT_KILL) };
22
23 if ctx.is_null() {
24 return Err(ErrorKind::FFI.into());
25 }
26
27 Ok(Context {
28 ctx,
29 })
30 }
31
32 fn allow_syscall(&mut self, syscall: Syscall) -> Result<()> {
33 debug!("seccomp: allowing syscall={:?}", syscall);
34 let ret = unsafe { seccomp_rule_add(self.ctx, SCMP_ACT_ALLOW, syscall.as_i32(), 0) };
35
36 if ret != 0 {
37 Err(ErrorKind::FFI.into())
38 } else {
39 Ok(())
40 }
41 }
42
43 fn load(&self) -> Result<()> {
44 let ret = unsafe { seccomp_load(self.ctx) };
45
46 if ret != 0 {
47 Err(ErrorKind::FFI.into())
48 } else {
49 Ok(())
50 }
51 }
52}
53
54impl Drop for Context {
55 fn drop(&mut self) {
56 unsafe {
57 seccomp_release(self.ctx)
58 };
59 }
60}
61
62pub fn activate_stage1() -> Result<()> {
63 let mut ctx = Context::init()?;
64
65 ctx.allow_syscall(Syscall::read)?;
66 ctx.allow_syscall(Syscall::write)?;
67 ctx.allow_syscall(Syscall::mmap)?;
68 ctx.allow_syscall(Syscall::mprotect)?;
69 ctx.allow_syscall(Syscall::getrandom)?;
70 ctx.allow_syscall(Syscall::futex)?;
71 ctx.allow_syscall(Syscall::openat)?;
72 #[cfg(not(target_arch = "aarch64"))]
73 ctx.allow_syscall(Syscall::open)?;
74 ctx.allow_syscall(Syscall::ioctl)?;
75 ctx.allow_syscall(Syscall::close)?;
76 #[cfg(not(target_arch = "aarch64"))]
77 ctx.allow_syscall(Syscall::readlink)?;
78 ctx.allow_syscall(Syscall::readlinkat)?;
79 #[cfg(not(target_arch = "aarch64"))]
80 ctx.allow_syscall(Syscall::mkdir)?;
81 ctx.allow_syscall(Syscall::mkdirat)?;
82 #[cfg(not(target_arch = "aarch64"))]
83 ctx.allow_syscall(Syscall::lstat)?;
84 ctx.allow_syscall(Syscall::fstat)?;
85 ctx.allow_syscall(Syscall::newfstatat)?;
86 #[cfg(not(target_arch = "aarch64"))]
87 ctx.allow_syscall(Syscall::unlink)?;
88 ctx.allow_syscall(Syscall::unlinkat)?;
89 #[cfg(not(target_arch = "aarch64"))]
90 ctx.allow_syscall(Syscall::symlink)?;
91 ctx.allow_syscall(Syscall::symlinkat)?;
92 ctx.allow_syscall(Syscall::getdents)?;
93 ctx.allow_syscall(Syscall::getpid)?;
94 ctx.allow_syscall(Syscall::getuid)?;
95 ctx.allow_syscall(Syscall::readv)?;
96 ctx.allow_syscall(Syscall::lseek)?;
97 ctx.allow_syscall(Syscall::eventfd2)?;
98 ctx.allow_syscall(Syscall::sched_getparam)?;
99 ctx.allow_syscall(Syscall::sched_getscheduler)?;
100 ctx.allow_syscall(Syscall::sched_setscheduler)?;
101 ctx.allow_syscall(Syscall::poll)?;
102 ctx.allow_syscall(Syscall::getsockname)?;
103 ctx.allow_syscall(Syscall::getsockopt)?;
104 ctx.allow_syscall(Syscall::getpeername)?;
105 ctx.allow_syscall(Syscall::sendto)?;
106 ctx.allow_syscall(Syscall::clone)?;
107 ctx.allow_syscall(Syscall::set_robust_list)?;
108 ctx.allow_syscall(Syscall::sigaltstack)?;
109 ctx.allow_syscall(Syscall::munmap)?;
110 ctx.allow_syscall(Syscall::sched_getaffinity)?;
111 ctx.allow_syscall(Syscall::pipe2)?;
112 ctx.allow_syscall(Syscall::epoll_create1)?;
113 ctx.allow_syscall(Syscall::epoll_ctl)?;
114 ctx.allow_syscall(Syscall::epoll_pwait)?;
115 #[cfg(not(target_arch = "aarch64"))]
116 ctx.allow_syscall(Syscall::epoll_wait)?;
117 #[cfg(not(target_arch = "aarch64"))]
118 ctx.allow_syscall(Syscall::stat)?;
119 ctx.allow_syscall(Syscall::socket)?;
120 ctx.allow_syscall(Syscall::bind)?;
121 ctx.allow_syscall(Syscall::listen)?;
122 #[cfg(not(target_arch = "aarch64"))]
123 ctx.allow_syscall(Syscall::chmod)?;
124 ctx.allow_syscall(Syscall::fchmodat)?;
125 ctx.allow_syscall(Syscall::accept4)?;
126 ctx.allow_syscall(Syscall::recvfrom)?;
127 ctx.allow_syscall(Syscall::shutdown)?;
128 ctx.allow_syscall(Syscall::connect)?;
129 ctx.allow_syscall(Syscall::nanosleep)?;
130 ctx.allow_syscall(Syscall::sched_yield)?;
131 ctx.allow_syscall(Syscall::madvise)?;
132 ctx.allow_syscall(Syscall::exit_group)?;
133 ctx.allow_syscall(Syscall::exit)?;
134 ctx.allow_syscall(Syscall::wait4)?;
135 ctx.allow_syscall(Syscall::fcntl)?;
136 ctx.allow_syscall(Syscall::brk)?;
137 ctx.allow_syscall(Syscall::rt_sigprocmask)?;
138 ctx.allow_syscall(Syscall::clock_gettime)?;
139 ctx.allow_syscall(Syscall::gettimeofday)?;
140 ctx.allow_syscall(Syscall::prctl)?; ctx.allow_syscall(Syscall::seccomp)?; ctx.allow_syscall(Syscall::capget)?; ctx.allow_syscall(Syscall::capset)?; ctx.allow_syscall(Syscall::chroot)?; ctx.allow_syscall(Syscall::chdir)?; ctx.load()?;
148
149 info!("stage 1/1 is active");
150
151 Ok(())
152}
153
154pub fn activate_tr1pd_stage2() -> Result<()> {
155 let mut ctx = Context::init()?;
156
157 ctx.allow_syscall(Syscall::read)?;
158 ctx.allow_syscall(Syscall::write)?;
159 ctx.allow_syscall(Syscall::mmap)?;
160 ctx.allow_syscall(Syscall::mprotect)?;
161 ctx.allow_syscall(Syscall::getrandom)?;
162 ctx.allow_syscall(Syscall::futex)?;
163 ctx.allow_syscall(Syscall::openat)?;
164 #[cfg(not(target_arch = "aarch64"))]
165 ctx.allow_syscall(Syscall::open)?;
166 ctx.allow_syscall(Syscall::ioctl)?;
167 ctx.allow_syscall(Syscall::close)?;
168 #[cfg(not(target_arch = "aarch64"))]
169 ctx.allow_syscall(Syscall::readlink)?;
170 ctx.allow_syscall(Syscall::readlinkat)?;
171 #[cfg(not(target_arch = "aarch64"))]
172 ctx.allow_syscall(Syscall::mkdir)?;
173 ctx.allow_syscall(Syscall::mkdirat)?;
174 #[cfg(not(target_arch = "aarch64"))]
175 ctx.allow_syscall(Syscall::lstat)?;
176 ctx.allow_syscall(Syscall::newfstatat)?;
177 #[cfg(not(target_arch = "aarch64"))]
178 ctx.allow_syscall(Syscall::unlink)?;
179 ctx.allow_syscall(Syscall::unlinkat)?;
180 #[cfg(not(target_arch = "aarch64"))]
181 ctx.allow_syscall(Syscall::symlink)?;
182 ctx.allow_syscall(Syscall::symlinkat)?;
183 ctx.allow_syscall(Syscall::sched_getparam)?;
184 ctx.allow_syscall(Syscall::sched_getscheduler)?;
185 ctx.allow_syscall(Syscall::sched_setscheduler)?;
186 ctx.allow_syscall(Syscall::getpeername)?;
187 ctx.allow_syscall(Syscall::eventfd2)?;
188 ctx.allow_syscall(Syscall::getpid)?;
189 ctx.allow_syscall(Syscall::poll)?;
190 ctx.allow_syscall(Syscall::sendto)?;
191 ctx.allow_syscall(Syscall::clone)?;
192 ctx.allow_syscall(Syscall::set_robust_list)?;
193 ctx.allow_syscall(Syscall::sigaltstack)?;
194 ctx.allow_syscall(Syscall::munmap)?;
195 ctx.allow_syscall(Syscall::sched_getaffinity)?;
196 ctx.allow_syscall(Syscall::pipe2)?;
197 ctx.allow_syscall(Syscall::epoll_create1)?;
198 ctx.allow_syscall(Syscall::epoll_ctl)?;
199 ctx.allow_syscall(Syscall::epoll_pwait)?;
200 #[cfg(not(target_arch = "aarch64"))]
201 ctx.allow_syscall(Syscall::epoll_wait)?;
202 #[cfg(not(target_arch = "aarch64"))]
203 ctx.allow_syscall(Syscall::stat)?;
204 ctx.allow_syscall(Syscall::socket)?;
205 ctx.allow_syscall(Syscall::bind)?;
206 ctx.allow_syscall(Syscall::listen)?;
207 #[cfg(not(target_arch = "aarch64"))]
208 ctx.allow_syscall(Syscall::chmod)?;
209 ctx.allow_syscall(Syscall::fchmodat)?;
210 ctx.allow_syscall(Syscall::accept4)?;
211 ctx.allow_syscall(Syscall::recvfrom)?;
212 ctx.allow_syscall(Syscall::shutdown)?;
213 ctx.allow_syscall(Syscall::connect)?;
214 ctx.allow_syscall(Syscall::nanosleep)?;
215 ctx.allow_syscall(Syscall::sched_yield)?;
216 ctx.allow_syscall(Syscall::madvise)?;
217 ctx.allow_syscall(Syscall::exit_group)?;
218 ctx.allow_syscall(Syscall::exit)?;
219 ctx.allow_syscall(Syscall::wait4)?;
220 ctx.allow_syscall(Syscall::fcntl)?;
221 ctx.allow_syscall(Syscall::brk)?;
222 ctx.allow_syscall(Syscall::clock_gettime)?;
223 ctx.load()?;
231
232 info!("stage 2/2 is active");
233
234 Ok(())
235}