From 15c555b335126e5210c2847048f85dd078e71cf7 Mon Sep 17 00:00:00 2001 From: David Gibson Date: Fri, 3 Jun 2016 18:42:00 +1000 Subject: [PATCH] altstack: Restore alternate signal stack state altstack relies on catching a SIGSEGV caused when overrunning the stack. This means that the SEGV handler itself can't use the already overflowed stack, and so we use sigaltstack() to assign the signal handler a different stack. On completion, altstack() clears the alternate signal stack. However, it's possible that the calling program could be using sigaltstack() for its own reasons, so it's more correct to restore the sigaltstack() state to that from the beginning of the altstack() call. This patch implements this behaviour. Signed-off-by: David Gibson --- ccan/altstack/altstack.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ccan/altstack/altstack.c b/ccan/altstack/altstack.c index edd79f68..62db343c 100644 --- a/ccan/altstack/altstack.c +++ b/ccan/altstack/altstack.c @@ -71,6 +71,7 @@ int altstack(rlim_t max, void *(*fn)(void *), void *arg, void **out) struct rlimit rl_save; struct sigaction sa_save; int errno_save; + stack_t ss_save; assert(max > 0 && fn); #define ok(x, y) ({ long __r = (long) (x); if (__r == -1) { bang(#x); if (y) goto out; } __r; }) @@ -98,7 +99,7 @@ int altstack(rlim_t max, void *(*fn)(void *), void *arg, void **out) stack_t ss = { .ss_sp = sigstk, .ss_size = sizeof(sigstk) }; struct sigaction sa = { .sa_handler = segvjmp, .sa_flags = SA_NODEFER|SA_RESETHAND|SA_ONSTACK }; - ok(sigaltstack(&ss, 0), 1); + ok(sigaltstack(&ss, &ss_save), 1); undo++; sigemptyset(&sa.sa_mask); @@ -131,7 +132,7 @@ out: case 4: ok(sigaction(SIGSEGV, &sa_save, 0), 0); case 3: - ok(sigaltstack(&(stack_t) { .ss_flags = SS_DISABLE }, 0), 0); + ok(sigaltstack(&ss_save, 0), 0); case 2: ok(munmap(m, max), 0); case 1: -- 2.39.2