test_exec_helper/
exec_helper.rs1#![no_std]
2#![no_main]
3
4#[cfg(not(test))]
5use core::panic::PanicInfo;
6use strat9_syscall::{call, error::Error};
7
8const F_GETFD: usize = 1;
9const HELPER_FD: usize = 19;
10const SIGUSR1: usize = 10;
11const SIGUSR2: usize = 12;
12const SIG_IGN: u64 = 1;
13const SS_DISABLE: i32 = 1;
14
15#[repr(C)]
16#[derive(Clone, Copy)]
17struct SigActionRaw {
18 sa_handler: u64,
19 sa_flags: u64,
20 sa_restorer: u64,
21 sa_mask: u64,
22}
23
24#[repr(C)]
25#[derive(Clone, Copy)]
26struct SigStackRaw {
27 ss_sp: u64,
28 ss_flags: i32,
29 ss_size: usize,
30}
31
32fn write_fd(fd: usize, msg: &str) {
33 let _ = call::write(fd, msg.as_bytes());
34}
35
36fn log(msg: &str) {
37 write_fd(1, msg);
38}
39
40fn log_err(msg: &str) {
41 write_fd(2, msg);
42}
43
44fn check_sigaction(signum: usize, expected_handler: u64, label: &str) -> bool {
45 let mut old = SigActionRaw {
46 sa_handler: 0,
47 sa_flags: 0,
48 sa_restorer: 0,
49 sa_mask: 0,
50 };
51 match call::sigaction(signum, 0, &mut old as *mut _ as usize) {
52 Ok(_) if old.sa_handler == expected_handler => true,
53 Ok(_) => {
54 log_err("[test_exec_helper] ");
55 log_err(label);
56 log_err(" mismatch\n");
57 false
58 }
59 Err(err) => {
60 log_err("[test_exec_helper] ");
61 log_err(label);
62 log_err(": ");
63 log_err(err.name());
64 log_err("\n");
65 false
66 }
67 }
68}
69
70fn check_sigaltstack_reset() -> bool {
71 let mut old = SigStackRaw {
72 ss_sp: 0,
73 ss_flags: 0,
74 ss_size: 0,
75 };
76 match call::sigaltstack(0, &mut old as *mut _ as usize) {
77 Ok(_) if (old.ss_flags & SS_DISABLE) != 0 => true,
78 Ok(_) => {
79 log_err("[test_exec_helper] sigaltstack still enabled\n");
80 false
81 }
82 Err(err) => {
83 log_err("[test_exec_helper] sigaltstack query: ");
84 log_err(err.name());
85 log_err("\n");
86 false
87 }
88 }
89}
90
91fn check_cloexec_closed() -> bool {
92 match call::fcntl(HELPER_FD, F_GETFD, 0) {
93 Err(Error::BadHandle) => true,
94 Err(err) => {
95 log_err("[test_exec_helper] cloexec query: ");
96 log_err(err.name());
97 log_err("\n");
98 false
99 }
100 Ok(_) => {
101 log_err("[test_exec_helper] cloexec fd still open\n");
102 false
103 }
104 }
105}
106
107#[cfg(not(test))]
108#[panic_handler]
109fn panic(_info: &PanicInfo) -> ! {
110 log_err("[test_exec_helper] panic\n");
111 call::exit(210)
112}
113
114#[no_mangle]
115pub extern "C" fn _start() -> ! {
116 log("[test_exec_helper] validating post-exec state\n");
117
118 let mut ok = true;
119 ok &= check_sigaction(SIGUSR1, 0, "SIGUSR1 reset to default");
120 ok &= check_sigaction(SIGUSR2, SIG_IGN, "SIGUSR2 preserved as SIG_IGN");
121 ok &= check_sigaltstack_reset();
122 ok &= check_cloexec_closed();
123
124 if ok {
125 log("[test_exec_helper] validation passed\n");
126 call::exit(0)
127 } else {
128 call::exit(1)
129 }
130}