1#![forbid(unsafe_code)]
11
12use std::{
13 fs::File,
14 os::fd::OwnedFd,
15 sync::{Arc, Condvar, Mutex, RwLock},
16};
17
18use ahash::{HashMapExt, HashSetExt};
19use libseccomp::ScmpSyscall;
20use nix::{errno::Errno, sys::socket::UnixAddr, unistd::Pid};
21use serde::{ser::SerializeMap, Serializer};
22
23use crate::{
24 confine::{ScmpNotifReq, SydArch},
25 elf::ExecutableFile,
26 hash::{SydHashMap, SydHashSet},
27 sigset::SydSigSet,
28};
29
30#[derive(Debug)]
32pub(crate) struct SysInterrupt {
33 pub(crate) handler: Pid,
35 pub(crate) request: ScmpNotifReq,
37 pub(crate) status: Option<OwnedFd>,
39 pub(crate) delete: bool,
42 pub(crate) signal: bool,
46 pub(crate) ignore_restart: bool,
49}
50
51pub(crate) type BlockVec = Vec<SysInterrupt>;
53
54pub(crate) type RestartMap = SydHashMap<Pid, SydSigSet>;
56
57#[derive(Debug)]
59pub(crate) struct SysInterruptMap {
60 pub(crate) sys_block: Arc<(Mutex<BlockVec>, Condvar)>,
62 pub(crate) sig_restart: Arc<Mutex<RestartMap>>,
65}
66
67#[derive(Debug)]
69pub(crate) struct ExecResult {
70 pub(crate) exe: ExecutableFile,
71 pub(crate) file: File,
72}
73
74pub(crate) type ErrorMap = SydHashMap<Pid, Option<Errno>>;
76
77pub(crate) type ChdirSet = SydHashSet<Pid>;
79
80pub(crate) type ExecvMap = SydHashMap<Pid, ExecResult>;
82
83pub(crate) type MmapSet = SydHashSet<Pid>;
85
86#[derive(Copy, Clone)]
96pub(crate) struct UnixVal {
97 pub(crate) pid: Pid,
98 pub(crate) addr: Option<UnixAddr>,
99 pub(crate) peer: Option<UnixAddr>,
100}
101pub(crate) type UnixMap = Arc<RwLock<SydHashMap<u64, UnixVal>>>;
102
103pub(crate) type PtraceMap = Arc<RwLock<SydHashMap<Pid, Pid>>>;
106
107#[derive(Debug)]
109pub(crate) struct SysResultMap {
110 pub(crate) trace_error: Arc<Mutex<ErrorMap>>,
112 pub(crate) trace_chdir: Arc<Mutex<ChdirSet>>,
114 pub(crate) trace_execv: Arc<Mutex<ExecvMap>>,
116 pub(crate) trace_mmap: Arc<Mutex<MmapSet>>,
118}
119
120pub(crate) type SighandleMap = SydHashMap<Pid, u64>;
122
123#[derive(Debug)]
127pub(crate) struct SignalMap {
128 pub(crate) sig_handle: Arc<Mutex<SighandleMap>>,
130}
131
132impl SysInterrupt {
133 pub(crate) fn new(
134 request: ScmpNotifReq,
135 handler: Pid,
136 ignore_restart: bool,
137 ) -> Result<Self, Errno> {
138 Ok(Self {
139 handler,
140 request,
141 ignore_restart,
142 status: None,
143 delete: false,
144 signal: false,
145 })
146 }
147
148 pub(crate) fn delete(&mut self) -> bool {
152 if self.status.is_some() {
158 self.delete = true;
159 true } else {
161 false }
163 }
164}
165
166impl serde::Serialize for SysInterrupt {
167 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
168 where
169 S: Serializer,
170 {
171 let mut map = serializer.serialize_map(Some(3))?;
172
173 let data = &self.request.data;
174 let syscall = ScmpSyscall::get_name_by_arch(data.syscall, data.arch)
175 .unwrap_or_else(|_| format!("{}", i32::from(data.syscall)));
176 let _ = map.serialize_entry("pid", &self.request.pid);
177 let _ = map.serialize_entry("sys", &syscall);
178 let _ = map.serialize_entry("arch", &SydArch::from(data.arch));
179 let _ = map.serialize_entry("args", &data.args);
180 let _ = map.serialize_entry("handler", &self.handler.as_raw());
181 let _ = map.serialize_entry("ignore_restart", &self.ignore_restart);
182
183 map.end()
184 }
185}
186
187pub(crate) fn unix_map_new() -> UnixMap {
189 Arc::new(RwLock::new(SydHashMap::default()))
190}
191
192pub(crate) fn ptrace_map_new() -> PtraceMap {
194 Arc::new(RwLock::new(SydHashMap::default()))
195}
196
197pub(crate) fn sys_interrupt_map_new() -> SysInterruptMap {
199 SysInterruptMap {
200 sys_block: Arc::new((Mutex::new(BlockVec::new()), Condvar::new())),
201 sig_restart: Arc::new(Mutex::new(RestartMap::new())),
202 }
203}
204
205pub(crate) fn sys_result_map_new() -> SysResultMap {
207 SysResultMap {
208 trace_error: Arc::new(Mutex::new(ErrorMap::new())),
209 trace_chdir: Arc::new(Mutex::new(ChdirSet::new())),
210 trace_execv: Arc::new(Mutex::new(ExecvMap::new())),
211 trace_mmap: Arc::new(Mutex::new(MmapSet::new())),
212 }
213}
214
215pub(crate) fn signal_map_new() -> SignalMap {
217 SignalMap {
218 sig_handle: Arc::new(Mutex::new(SighandleMap::new())),
219 }
220}