at master 2.3 kB view raw
1// SPDX-License-Identifier: GPL-2.0-only 2 3#define _GNU_SOURCE 4#include <signal.h> 5#include <stdio.h> 6#include <stdbool.h> 7#include <string.h> 8#include <err.h> 9#include <errno.h> 10#include <limits.h> 11#include <sys/mman.h> 12#include <sys/auxv.h> 13#include <sys/prctl.h> 14#include <sys/resource.h> 15#include <setjmp.h> 16 17#include "helpers.h" 18 19/* sigaltstack()-enforced minimum stack */ 20#define ENFORCED_MINSIGSTKSZ 2048 21 22#ifndef AT_MINSIGSTKSZ 23# define AT_MINSIGSTKSZ 51 24#endif 25 26static int nerrs; 27 28static bool sigalrm_expected; 29 30static unsigned long at_minstack_size; 31 32static int setup_altstack(void *start, unsigned long size) 33{ 34 stack_t ss; 35 36 memset(&ss, 0, sizeof(ss)); 37 ss.ss_size = size; 38 ss.ss_sp = start; 39 40 return sigaltstack(&ss, NULL); 41} 42 43static jmp_buf jmpbuf; 44 45static void sigsegv(int sig, siginfo_t *info, void *ctx_void) 46{ 47 if (sigalrm_expected) { 48 printf("[FAIL]\tWrong signal delivered: SIGSEGV (expected SIGALRM)."); 49 nerrs++; 50 } else { 51 printf("[OK]\tSIGSEGV signal delivered.\n"); 52 } 53 54 siglongjmp(jmpbuf, 1); 55} 56 57static void sigalrm(int sig, siginfo_t *info, void *ctx_void) 58{ 59 if (!sigalrm_expected) { 60 printf("[FAIL]\tWrong signal delivered: SIGALRM (expected SIGSEGV)."); 61 nerrs++; 62 } else { 63 printf("[OK]\tSIGALRM signal delivered.\n"); 64 } 65} 66 67static void test_sigaltstack(void *altstack, unsigned long size) 68{ 69 if (setup_altstack(altstack, size)) 70 err(1, "sigaltstack()"); 71 72 sigalrm_expected = (size > at_minstack_size) ? true : false; 73 74 sethandler(SIGSEGV, sigsegv, 0); 75 sethandler(SIGALRM, sigalrm, SA_ONSTACK); 76 77 if (!sigsetjmp(jmpbuf, 1)) { 78 printf("[RUN]\tTest an alternate signal stack of %ssufficient size.\n", 79 sigalrm_expected ? "" : "in"); 80 printf("\tRaise SIGALRM. %s is expected to be delivered.\n", 81 sigalrm_expected ? "It" : "SIGSEGV"); 82 raise(SIGALRM); 83 } 84 85 clearhandler(SIGALRM); 86 clearhandler(SIGSEGV); 87} 88 89int main(void) 90{ 91 void *altstack; 92 93 at_minstack_size = getauxval(AT_MINSIGSTKSZ); 94 95 altstack = mmap(NULL, at_minstack_size + SIGSTKSZ, PROT_READ | PROT_WRITE, 96 MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); 97 if (altstack == MAP_FAILED) 98 err(1, "mmap()"); 99 100 if ((ENFORCED_MINSIGSTKSZ + 1) < at_minstack_size) 101 test_sigaltstack(altstack, ENFORCED_MINSIGSTKSZ + 1); 102 103 test_sigaltstack(altstack, at_minstack_size + SIGSTKSZ); 104 105 return nerrs == 0 ? 0 : 1; 106}