extrasafe_multiarch/builtins/
network.rs1use std::collections::{HashMap, HashSet};
4
5use crate::syscalls::Sysno;
6
7use super::YesReally;
8use crate::{SeccompRule, RuleSet};
9
10const NET_IO_SYSCALLS: &[Sysno] = &[
14 #[cfg(enabled_arch = "x86_64")]
15 Sysno::epoll_create,
16 Sysno::epoll_create1, Sysno::epoll_ctl,
17 #[cfg(enabled_arch = "x86_64")]
18 Sysno::epoll_wait,
19 Sysno::epoll_pwait, Sysno::epoll_pwait2,
20 #[cfg(enabled_arch = "x86_64")]
21 Sysno::select,
22 Sysno::pselect6,
23 #[cfg(enabled_arch = "x86_64")]
24 Sysno::poll,
25 Sysno::ppoll, Sysno::accept, Sysno::accept4,
26 #[cfg(enabled_arch = "x86_64")]
28 Sysno::eventfd,
29 Sysno::eventfd2,
30 Sysno::fcntl, Sysno::ioctl,
32 Sysno::getsockopt,
33 Sysno::setsockopt,
34
35 Sysno::getpeername,
37 Sysno::getsockname,
38];
39
40const NET_READ_SYSCALLS: &[Sysno] = &[Sysno::listen,
42 Sysno::recvfrom, Sysno::recvmsg, Sysno::recvmmsg,
43 Sysno::read, Sysno::readv, Sysno::preadv, Sysno::preadv2];
44const NET_WRITE_SYSCALLS: &[Sysno] = &[Sysno::sendto, Sysno::sendmsg, Sysno::sendmmsg,
45 Sysno::sendfile,
46 Sysno::write, Sysno::writev, Sysno::pwritev, Sysno::pwritev2];
47
48#[must_use]
72pub struct Networking {
73 allowed: HashSet<Sysno>,
75 custom: HashMap<Sysno, Vec<SeccompRule>>,
77}
78
79impl Networking {
80 pub fn nothing() -> Networking {
82 Networking {
83 allowed: HashSet::new(),
84 custom: HashMap::new(),
85 }
86 }
87
88 pub fn allow_running_tcp_servers(mut self) -> Networking {
91 self.allowed.extend(NET_IO_SYSCALLS);
92 self.allowed.extend(NET_READ_SYSCALLS);
93 self.allowed.extend(NET_WRITE_SYSCALLS);
94
95 self
96 }
97
98 pub fn allow_start_tcp_servers(mut self) -> YesReally<Networking> {
106 const AF_INET: u64 = libc::AF_INET as u64;
107 const AF_INET6: u64 = libc::AF_INET6 as u64;
108 const SOCK_STREAM: u64 = libc::SOCK_STREAM as u64;
109
110 let rule = SeccompRule::new(Sysno::socket)
112 .and_condition(seccomp_arg_filter!(arg0 & AF_INET == AF_INET))
113 .and_condition(seccomp_arg_filter!(arg1 & SOCK_STREAM == SOCK_STREAM));
114 self.custom.entry(Sysno::socket)
115 .or_insert_with(Vec::new)
116 .push(rule);
117 let rule = SeccompRule::new(Sysno::socket)
119 .and_condition(seccomp_arg_filter!(arg0 & AF_INET6 == AF_INET6))
120 .and_condition(seccomp_arg_filter!(arg1 & SOCK_STREAM == SOCK_STREAM));
121 self.custom.entry(Sysno::socket)
122 .or_insert_with(Vec::new)
123 .push(rule);
124
125 self.allowed.extend(&[Sysno::bind]);
128 self.allowed.extend(NET_IO_SYSCALLS);
129 self.allowed.extend(NET_READ_SYSCALLS);
130 self.allowed.extend(NET_WRITE_SYSCALLS);
131
132 YesReally::new(self)
133 }
134
135 pub fn allow_running_udp_sockets(mut self) -> Networking {
138 self.allowed.extend(NET_IO_SYSCALLS);
139 self.allowed.extend(NET_READ_SYSCALLS);
140 self.allowed.extend(NET_WRITE_SYSCALLS);
141
142 self
143 }
144
145 pub fn allow_start_udp_servers(mut self) -> YesReally<Networking> {
152 const AF_INET: u64 = libc::AF_INET as u64;
153 const AF_INET6: u64 = libc::AF_INET6 as u64;
154 const SOCK_DGRAM: u64 = libc::SOCK_DGRAM as u64;
155
156 let rule = SeccompRule::new(Sysno::socket)
158 .and_condition(seccomp_arg_filter!(arg0 & AF_INET == AF_INET))
159 .and_condition(seccomp_arg_filter!(arg1 & SOCK_DGRAM == SOCK_DGRAM));
160 self.custom.entry(Sysno::socket)
161 .or_insert_with(Vec::new)
162 .push(rule);
163 let rule = SeccompRule::new(Sysno::socket)
165 .and_condition(seccomp_arg_filter!(arg0 & AF_INET6 == AF_INET6))
166 .and_condition(seccomp_arg_filter!(arg1 & SOCK_DGRAM == SOCK_DGRAM));
167 self.custom.entry(Sysno::socket)
168 .or_insert_with(Vec::new)
169 .push(rule);
170
171 self.allowed.extend(&[Sysno::bind]);
172 self.allowed.extend(NET_IO_SYSCALLS);
173 self.allowed.extend(NET_READ_SYSCALLS);
174 self.allowed.extend(NET_WRITE_SYSCALLS);
175
176 YesReally::new(self)
177 }
178
179 pub fn allow_connect(mut self) -> YesReally<Networking> {
185 self.allowed.extend(&[Sysno::connect]);
186 YesReally::new(self)
187 }
188
189 pub fn allow_start_tcp_clients(mut self) -> Networking {
196 const AF_INET: u64 = libc::AF_INET as u64;
197 const AF_INET6: u64 = libc::AF_INET6 as u64;
198 const SOCK_STREAM: u64 = libc::SOCK_STREAM as u64;
199
200 let rule = SeccompRule::new(Sysno::socket)
202 .and_condition(seccomp_arg_filter!(arg0 & AF_INET == AF_INET))
203 .and_condition(seccomp_arg_filter!(arg1 & SOCK_STREAM == SOCK_STREAM));
204 self.custom.entry(Sysno::socket)
205 .or_insert_with(Vec::new)
206 .push(rule);
207 let rule = SeccompRule::new(Sysno::socket)
209 .and_condition(seccomp_arg_filter!(arg0 & AF_INET6 == AF_INET6))
210 .and_condition(seccomp_arg_filter!(arg1 & SOCK_STREAM == SOCK_STREAM));
211 self.custom.entry(Sysno::socket)
212 .or_insert_with(Vec::new)
213 .push(rule);
214
215 self.allowed.extend(&[Sysno::connect]);
216 self.allowed.extend(NET_IO_SYSCALLS);
217 self.allowed.extend(NET_READ_SYSCALLS);
218 self.allowed.extend(NET_WRITE_SYSCALLS);
219
220 self
221 }
222
223 pub fn allow_running_tcp_clients(mut self) -> Networking {
229 self.allowed.extend(NET_IO_SYSCALLS);
230 self.allowed.extend(NET_READ_SYSCALLS);
231 self.allowed.extend(NET_WRITE_SYSCALLS);
232
233 self
234 }
235
236 pub fn allow_start_unix_servers(mut self) -> YesReally<Networking> {
243 const AF_UNIX: u64 = libc::AF_UNIX as u64;
244 const SOCK_STREAM: u64 = libc::SOCK_STREAM as u64;
245 const SOCK_DGRAM: u64 = libc::SOCK_DGRAM as u64;
246
247 let rule = SeccompRule::new(Sysno::socket)
249 .and_condition(seccomp_arg_filter!(arg0 & AF_UNIX == AF_UNIX))
250 .and_condition(seccomp_arg_filter!(arg1 & SOCK_STREAM == SOCK_STREAM));
251 self.custom.entry(Sysno::socket)
252 .or_insert_with(Vec::new)
253 .push(rule);
254 let rule = SeccompRule::new(Sysno::socket)
256 .and_condition(seccomp_arg_filter!(arg0 & AF_UNIX == AF_UNIX))
257 .and_condition(seccomp_arg_filter!(arg1 & SOCK_DGRAM == SOCK_DGRAM));
258 self.custom.entry(Sysno::socket)
259 .or_insert_with(Vec::new)
260 .push(rule);
261
262 self.allowed.extend(&[Sysno::bind]);
263 self.allowed.extend(NET_IO_SYSCALLS);
264 self.allowed.extend(NET_READ_SYSCALLS);
265 self.allowed.extend(NET_WRITE_SYSCALLS);
266
267 YesReally::new(self)
268 }
269
270 pub fn allow_running_unix_servers(mut self) -> Networking {
273 self.allowed.extend(NET_IO_SYSCALLS);
274 self.allowed.extend(NET_READ_SYSCALLS);
275 self.allowed.extend(NET_WRITE_SYSCALLS);
276
277 self
278 }
279
280 pub fn allow_running_unix_clients(mut self) -> Networking {
286 self.allowed.extend(NET_IO_SYSCALLS);
287 self.allowed.extend(NET_READ_SYSCALLS);
288 self.allowed.extend(NET_WRITE_SYSCALLS);
289
290 self
291 }
292}
293
294impl RuleSet for Networking {
295 fn simple_rules(&self) -> Vec<crate::syscalls::Sysno> {
296 self.allowed.iter().copied().collect()
297 }
298
299 fn conditional_rules(&self) -> HashMap<crate::syscalls::Sysno, Vec<SeccompRule>> {
300 self.custom.clone()
301 }
302
303 fn name(&self) -> &'static str {
304 "Networking"
305 }
306}