this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add a sigaltstack guard by default and change default size to 16KiB

It turns out that in some cases (with nested signals) the default
sigaltstack of 8KiB is not enough; 16KiB seems to be enough
for these cases (for now).

I suspected there was some stack corruption/overflow going on, so I
added a guard page for the default handler and found that, yes, we were
overflowing the default sigstack. That's why I've left the guard page
enabled by default now for sigstacks; if we do ever overflow it, we'll
know right away (rather than with some seemingly unrelated error later
on).

+25 -6
+25 -6
src/kernel/emulation/linux/signal/sigexc.c
··· 28 28 extern _libkernel_functions_t _libkernel_functions; 29 29 30 30 void darling_sigexc_uninstall(void); 31 - void sigrt_handler(int signum, struct linux_siginfo* info, void* ctxt); 31 + void sigrt_handler(int signum, struct linux_siginfo* info, struct linux_ucontext* ctxt); 32 32 33 - static char sigexc_altstack[8*1024]; 34 - size_t default_sigaltstack_size = sizeof(sigexc_altstack); 33 + #define SIGEXC_STACK_SIZE (16ULL * 1024ULL) 34 + 35 + #ifndef SIGALTSTACK_GUARD 36 + #define SIGALTSTACK_GUARD 1 37 + #endif 38 + 39 + #if SIGALTSTACK_GUARD 40 + // align it on a page boundary so mprotect works properly 41 + static char sigexc_altstack[SIGEXC_STACK_SIZE + 4096ULL] __attribute__((aligned(4096))); 42 + #else 43 + static char sigexc_altstack[SIGEXC_STACK_SIZE]; 44 + #endif 45 + size_t default_sigaltstack_size = SIGEXC_STACK_SIZE; 35 46 36 47 #if defined(__x86_64__) 37 48 static void mcontext_to_thread_state(const struct linux_gregset* regs, x86_thread_state64_t* s); ··· 84 95 int rv; 85 96 struct linux_sigaction sa; 86 97 87 - sa.sa_sigaction = sigrt_handler; 98 + sa.sa_sigaction = (linux_sig_handler*)sigrt_handler; 88 99 sa.sa_mask = (1ull << (SIGNAL_SIGEXC_SUSPEND-1)); 89 100 sa.sa_flags = LINUX_SA_RESTORER | LINUX_SA_SIGINFO | LINUX_SA_RESTART | LINUX_SA_ONSTACK; 90 101 sa.sa_restorer = sig_restorer; ··· 132 143 #endif 133 144 } 134 145 135 - void sigrt_handler(int signum, struct linux_siginfo* info, void* ctxt) 146 + void sigrt_handler(int signum, struct linux_siginfo* info, struct linux_ucontext* ctxt) 136 147 { 137 148 dserver_rpc_interrupt_enter(); 138 149 ··· 184 195 sizeof(sa.sa_mask)); 185 196 } 186 197 198 + #if SIGALTSTACK_GUARD 199 + sys_mprotect(sigexc_altstack, 4096, PROT_NONE); 200 + #endif 201 + 187 202 struct bsd_stack newstack = { 203 + #if SIGALTSTACK_GUARD 204 + .ss_sp = sigexc_altstack + 4096, 205 + #else 188 206 .ss_sp = sigexc_altstack, 189 - .ss_size = sizeof(sigexc_altstack), 207 + #endif 208 + .ss_size = SIGEXC_STACK_SIZE, 190 209 .ss_flags = 0 191 210 }; 192 211 sys_sigaltstack(&newstack, NULL);