preemptive_threads/security/
mod.rs1pub mod stack_protection;
7pub mod cfi;
8pub mod isolation;
9pub mod crypto_rng;
10pub mod aslr;
11pub mod audit;
12
13use portable_atomic::{AtomicBool, AtomicU64, Ordering};
14use crate::errors::ThreadError;
15
16#[derive(Debug, Clone, Copy)]
18pub struct SecurityConfig {
19 pub enable_stack_canaries: bool,
21 pub enable_guard_pages: bool,
23 pub enable_cfi: bool,
25 pub enable_thread_isolation: bool,
27 pub enable_aslr: bool,
29 pub enable_audit_logging: bool,
31 pub use_secure_rng: bool,
33 pub panic_on_violation: bool,
35}
36
37impl Default for SecurityConfig {
38 fn default() -> Self {
39 Self {
40 enable_stack_canaries: cfg!(feature = "hardened"),
41 enable_guard_pages: cfg!(feature = "mmu"),
42 enable_cfi: cfg!(feature = "hardened"),
43 enable_thread_isolation: false, enable_aslr: cfg!(feature = "hardened"),
45 enable_audit_logging: cfg!(debug_assertions),
46 use_secure_rng: true,
47 panic_on_violation: cfg!(debug_assertions),
48 }
49 }
50}
51
52#[derive(Debug, Clone, Copy, PartialEq, Eq)]
54pub enum SecurityViolation {
55 StackCanaryViolation,
57 GuardPageViolation,
59 CfiViolation,
61 IsolationViolation,
63 MemoryViolation,
65 ResourceViolation,
67 CryptoViolation,
69}
70
71#[derive(Debug, Clone, Copy, PartialEq, Eq)]
73pub enum ViolationResponse {
74 Continue,
76 TerminateThread,
78 Panic,
80}
81
82#[repr(align(64))] pub struct SecurityState {
85 pub total_violations: AtomicU64,
87 pub stack_violations: AtomicU64,
89 pub guard_violations: AtomicU64,
90 pub cfi_violations: AtomicU64,
91 pub isolation_violations: AtomicU64,
92 pub memory_violations: AtomicU64,
93 pub resource_violations: AtomicU64,
94 pub crypto_violations: AtomicU64,
95
96 pub canaries_enabled: AtomicBool,
98 pub guards_enabled: AtomicBool,
99 pub cfi_enabled: AtomicBool,
100 pub isolation_enabled: AtomicBool,
101 pub aslr_enabled: AtomicBool,
102 pub audit_enabled: AtomicBool,
103
104 config: SecurityConfig,
106}
107
108impl SecurityState {
109 pub const fn new(config: SecurityConfig) -> Self {
110 Self {
111 total_violations: AtomicU64::new(0),
112 stack_violations: AtomicU64::new(0),
113 guard_violations: AtomicU64::new(0),
114 cfi_violations: AtomicU64::new(0),
115 isolation_violations: AtomicU64::new(0),
116 memory_violations: AtomicU64::new(0),
117 resource_violations: AtomicU64::new(0),
118 crypto_violations: AtomicU64::new(0),
119 canaries_enabled: AtomicBool::new(config.enable_stack_canaries),
120 guards_enabled: AtomicBool::new(config.enable_guard_pages),
121 cfi_enabled: AtomicBool::new(config.enable_cfi),
122 isolation_enabled: AtomicBool::new(config.enable_thread_isolation),
123 aslr_enabled: AtomicBool::new(config.enable_aslr),
124 audit_enabled: AtomicBool::new(config.enable_audit_logging),
125 config,
126 }
127 }
128
129 pub fn record_violation(&self, violation: SecurityViolation) -> ViolationResponse {
131 self.total_violations.fetch_add(1, Ordering::Relaxed);
133
134 match violation {
135 SecurityViolation::StackCanaryViolation => {
136 self.stack_violations.fetch_add(1, Ordering::Relaxed);
137 }
138 SecurityViolation::GuardPageViolation => {
139 self.guard_violations.fetch_add(1, Ordering::Relaxed);
140 }
141 SecurityViolation::CfiViolation => {
142 self.cfi_violations.fetch_add(1, Ordering::Relaxed);
143 }
144 SecurityViolation::IsolationViolation => {
145 self.isolation_violations.fetch_add(1, Ordering::Relaxed);
146 }
147 SecurityViolation::MemoryViolation => {
148 self.memory_violations.fetch_add(1, Ordering::Relaxed);
149 }
150 SecurityViolation::ResourceViolation => {
151 self.resource_violations.fetch_add(1, Ordering::Relaxed);
152 }
153 SecurityViolation::CryptoViolation => {
154 self.crypto_violations.fetch_add(1, Ordering::Relaxed);
155 }
156 }
157
158 if self.audit_enabled.load(Ordering::Relaxed) {
160 audit::log_security_violation(violation);
161 }
162
163 if self.config.panic_on_violation {
165 ViolationResponse::Panic
166 } else {
167 match violation {
168 SecurityViolation::StackCanaryViolation |
169 SecurityViolation::GuardPageViolation |
170 SecurityViolation::CfiViolation => ViolationResponse::TerminateThread,
171 _ => ViolationResponse::Continue,
172 }
173 }
174 }
175
176 pub fn get_stats(&self) -> SecurityStats {
178 SecurityStats {
179 total_violations: self.total_violations.load(Ordering::Relaxed),
180 stack_violations: self.stack_violations.load(Ordering::Relaxed),
181 guard_violations: self.guard_violations.load(Ordering::Relaxed),
182 cfi_violations: self.cfi_violations.load(Ordering::Relaxed),
183 isolation_violations: self.isolation_violations.load(Ordering::Relaxed),
184 memory_violations: self.memory_violations.load(Ordering::Relaxed),
185 resource_violations: self.resource_violations.load(Ordering::Relaxed),
186 crypto_violations: self.crypto_violations.load(Ordering::Relaxed),
187 features_enabled: FeaturesEnabled {
188 canaries: self.canaries_enabled.load(Ordering::Relaxed),
189 guard_pages: self.guards_enabled.load(Ordering::Relaxed),
190 cfi: self.cfi_enabled.load(Ordering::Relaxed),
191 isolation: self.isolation_enabled.load(Ordering::Relaxed),
192 aslr: self.aslr_enabled.load(Ordering::Relaxed),
193 audit: self.audit_enabled.load(Ordering::Relaxed),
194 },
195 }
196 }
197}
198
199#[derive(Debug, Clone)]
201pub struct SecurityStats {
202 pub total_violations: u64,
203 pub stack_violations: u64,
204 pub guard_violations: u64,
205 pub cfi_violations: u64,
206 pub isolation_violations: u64,
207 pub memory_violations: u64,
208 pub resource_violations: u64,
209 pub crypto_violations: u64,
210 pub features_enabled: FeaturesEnabled,
211}
212
213#[derive(Debug, Clone)]
214pub struct FeaturesEnabled {
215 pub canaries: bool,
216 pub guard_pages: bool,
217 pub cfi: bool,
218 pub isolation: bool,
219 pub aslr: bool,
220 pub audit: bool,
221}
222
223pub static SECURITY_STATE: SecurityState = SecurityState::new(SecurityConfig {
225 enable_stack_canaries: cfg!(feature = "hardened"),
226 enable_guard_pages: cfg!(feature = "mmu"),
227 enable_cfi: cfg!(feature = "hardened"),
228 enable_thread_isolation: false,
229 enable_aslr: cfg!(feature = "hardened"),
230 enable_audit_logging: cfg!(debug_assertions),
231 use_secure_rng: true,
232 panic_on_violation: cfg!(debug_assertions),
233});
234
235pub fn init_security(config: SecurityConfig) -> Result<(), ThreadError> {
237 if config.enable_stack_canaries || config.enable_guard_pages {
239 stack_protection::init_stack_protection(config)?;
240 }
241
242 if config.enable_cfi {
244 cfi::init_cfi_protection(config)?;
245 }
246
247 if config.enable_thread_isolation {
249 isolation::init_thread_isolation(config)?;
250 }
251
252 if config.use_secure_rng {
254 crypto_rng::init_secure_rng()?;
255 }
256
257 if config.enable_aslr {
259 aslr::init_aslr(config)?;
260 }
261
262 if config.enable_audit_logging {
264 audit::init_audit_logging(config)?;
265 }
266
267 Ok(())
270}
271
272fn count_enabled_features(config: &SecurityConfig) -> usize {
274 let mut count = 0;
275 if config.enable_stack_canaries { count += 1; }
276 if config.enable_guard_pages { count += 1; }
277 if config.enable_cfi { count += 1; }
278 if config.enable_thread_isolation { count += 1; }
279 if config.enable_aslr { count += 1; }
280 if config.enable_audit_logging { count += 1; }
281 if config.use_secure_rng { count += 1; }
282 count
283}
284
285pub fn handle_security_violation(violation: SecurityViolation) -> ! {
287 let response = SECURITY_STATE.record_violation(violation);
288
289 match response {
290 ViolationResponse::Continue => {
291 panic!("Security violation handler requested continue for serious violation: {:?}", violation);
293 }
294 ViolationResponse::TerminateThread => {
295 crate::exit_thread();
297 unreachable!("Thread should have been terminated");
298 }
299 ViolationResponse::Panic => {
300 panic!("Security violation detected: {:?}", violation);
301 }
302 }
303}
304
305pub fn get_security_stats() -> SecurityStats {
307 SECURITY_STATE.get_stats()
308}
309
310pub fn configure_security_feature(feature: SecurityFeature, enabled: bool) {
312 match feature {
313 SecurityFeature::StackCanaries => {
314 SECURITY_STATE.canaries_enabled.store(enabled, Ordering::Relaxed);
315 }
316 SecurityFeature::GuardPages => {
317 SECURITY_STATE.guards_enabled.store(enabled, Ordering::Relaxed);
318 }
319 SecurityFeature::Cfi => {
320 SECURITY_STATE.cfi_enabled.store(enabled, Ordering::Relaxed);
321 }
322 SecurityFeature::Isolation => {
323 SECURITY_STATE.isolation_enabled.store(enabled, Ordering::Relaxed);
324 }
325 SecurityFeature::Aslr => {
326 SECURITY_STATE.aslr_enabled.store(enabled, Ordering::Relaxed);
327 }
328 SecurityFeature::Audit => {
329 SECURITY_STATE.audit_enabled.store(enabled, Ordering::Relaxed);
330 }
331 }
332}
333
334#[derive(Debug, Clone, Copy, PartialEq, Eq)]
336pub enum SecurityFeature {
337 StackCanaries,
338 GuardPages,
339 Cfi,
340 Isolation,
341 Aslr,
342 Audit,
343}