File Index
Files and directories
Sign in
FILE

sigaltstack.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/x86/sigaltstack.c C
  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}
~/ Read-only file preview.