106 lines · 2.3 KB · C
RawDownload
// SPDX-License-Identifier: GPL-2.0-only #define _GNU_SOURCE#include <signal.h>#include <stdio.h>#include <stdbool.h>#include <string.h>#include <err.h>#include <errno.h>#include <limits.h>#include <sys/mman.h>#include <sys/auxv.h>#include <sys/prctl.h>#include <sys/resource.h>#include <setjmp.h> #include "helpers.h" /* sigaltstack()-enforced minimum stack */#define ENFORCED_MINSIGSTKSZ	2048 #ifndef AT_MINSIGSTKSZ#  define AT_MINSIGSTKSZ	51#endif static int nerrs; static bool sigalrm_expected; static unsigned long at_minstack_size; static int setup_altstack(void *start, unsigned long size){	stack_t ss; 	memset(&ss, 0, sizeof(ss));	ss.ss_size = size;	ss.ss_sp = start; 	return sigaltstack(&ss, NULL);} static jmp_buf jmpbuf; static void sigsegv(int sig, siginfo_t *info, void *ctx_void){	if (sigalrm_expected) {		printf("[FAIL]\tWrong signal delivered: SIGSEGV (expected SIGALRM).");		nerrs++;	} else {		printf("[OK]\tSIGSEGV signal delivered.\n");	} 	siglongjmp(jmpbuf, 1);} static void sigalrm(int sig, siginfo_t *info, void *ctx_void){	if (!sigalrm_expected) {		printf("[FAIL]\tWrong signal delivered: SIGALRM (expected SIGSEGV).");		nerrs++;	} else {		printf("[OK]\tSIGALRM signal delivered.\n");	}} static void test_sigaltstack(void *altstack, unsigned long size){	if (setup_altstack(altstack, size))		err(1, "sigaltstack()"); 	sigalrm_expected = (size > at_minstack_size) ? true : false; 	sethandler(SIGSEGV, sigsegv, 0);	sethandler(SIGALRM, sigalrm, SA_ONSTACK); 	if (!sigsetjmp(jmpbuf, 1)) {		printf("[RUN]\tTest an alternate signal stack of %ssufficient size.\n",		       sigalrm_expected ? "" : "in");		printf("\tRaise SIGALRM. %s is expected to be delivered.\n",		       sigalrm_expected ? "It" : "SIGSEGV");		raise(SIGALRM);	} 	clearhandler(SIGALRM);	clearhandler(SIGSEGV);} int main(void){	void *altstack; 	at_minstack_size = getauxval(AT_MINSIGSTKSZ); 	altstack = mmap(NULL, at_minstack_size + SIGSTKSZ, PROT_READ | PROT_WRITE,			MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);	if (altstack == MAP_FAILED)		err(1, "mmap()"); 	if ((ENFORCED_MINSIGSTKSZ + 1) < at_minstack_size)		test_sigaltstack(altstack, ENFORCED_MINSIGSTKSZ + 1); 	test_sigaltstack(altstack, at_minstack_size + SIGSTKSZ); 	return nerrs == 0 ? 0 : 1;}