xref: /freebsd/tools/test/stress2/misc/sigaltstack.sh (revision 8a272653d9fbd9fc37691c9aad6a05089b4ecb4d)
1*8a272653SPeter Holm#!/bin/sh
2*8a272653SPeter Holm
3*8a272653SPeter Holm# sigaltstack(2) regression test by Steven Hartland <killing@multiplay.co.uk>
4*8a272653SPeter Holm# Wrong altsigstack clearing on exec
5*8a272653SPeter Holm# https://github.com/golang/go/issues/15658#issuecomment-287276856
6*8a272653SPeter Holm
7*8a272653SPeter Holm# Fixed by r315453
8*8a272653SPeter Holm
9*8a272653SPeter Holmcd /tmp
10*8a272653SPeter Holmcat > test-sigs.c <<EOF
11*8a272653SPeter Holm#include <errno.h>
12*8a272653SPeter Holm#include <signal.h>
13*8a272653SPeter Holm#include <stdio.h>
14*8a272653SPeter Holm#include <stdlib.h>
15*8a272653SPeter Holm#include <string.h>
16*8a272653SPeter Holm#include <unistd.h>
17*8a272653SPeter Holm#include <time.h>
18*8a272653SPeter Holm#include <pthread.h>
19*8a272653SPeter Holm
20*8a272653SPeter Holmextern char **environ;
21*8a272653SPeter Holm
22*8a272653SPeter Holmstatic void
23*8a272653SPeter Holmdie(const char *s)
24*8a272653SPeter Holm{
25*8a272653SPeter Holm       perror(s);
26*8a272653SPeter Holm       exit(EXIT_FAILURE);
27*8a272653SPeter Holm}
28*8a272653SPeter Holm
29*8a272653SPeter Holmstatic void
30*8a272653SPeter Holmsetstack(void *arg __unused)
31*8a272653SPeter Holm{
32*8a272653SPeter Holm	stack_t ss;
33*8a272653SPeter Holm
34*8a272653SPeter Holm	ss.ss_sp = malloc(SIGSTKSZ);
35*8a272653SPeter Holm	if (ss.ss_sp == NULL)
36*8a272653SPeter Holm		die("malloc");
37*8a272653SPeter Holm
38*8a272653SPeter Holm	ss.ss_size = SIGSTKSZ;
39*8a272653SPeter Holm	ss.ss_flags = 0;
40*8a272653SPeter Holm	if (sigaltstack(&ss, NULL) < 0)
41*8a272653SPeter Holm		die("sigaltstack set");
42*8a272653SPeter Holm}
43*8a272653SPeter Holm
44*8a272653SPeter Holmstatic void *
45*8a272653SPeter Holmthread_exec(void *arg)
46*8a272653SPeter Holm{
47*8a272653SPeter Holm	struct timespec ts = {0, 1000};
48*8a272653SPeter Holm	char *argv[] = {"./test-sigs", "no-more", 0};
49*8a272653SPeter Holm
50*8a272653SPeter Holm	setstack(arg);
51*8a272653SPeter Holm	nanosleep(&ts, NULL);
52*8a272653SPeter Holm
53*8a272653SPeter Holm	execve(argv[0], &argv[0], environ);
54*8a272653SPeter Holm	die("exec failed");
55*8a272653SPeter Holm
56*8a272653SPeter Holm	return NULL;
57*8a272653SPeter Holm}
58*8a272653SPeter Holm
59*8a272653SPeter Holmstatic void *
60*8a272653SPeter Holmthread_sleep(void *arg __unused)
61*8a272653SPeter Holm{
62*8a272653SPeter Holm	sleep(10);
63*8a272653SPeter Holm
64*8a272653SPeter Holm	return NULL;
65*8a272653SPeter Holm}
66*8a272653SPeter Holm
67*8a272653SPeter Holmint
68*8a272653SPeter Holmmain(int argc, char** argv __unused)
69*8a272653SPeter Holm{
70*8a272653SPeter Holm	int j;
71*8a272653SPeter Holm	pthread_t tid1, tid2;
72*8a272653SPeter Holm
73*8a272653SPeter Holm	if (argc != 1) {
74*8a272653SPeter Holm		stack_t ss;
75*8a272653SPeter Holm
76*8a272653SPeter Holm		if (sigaltstack(NULL, &ss) < 0)
77*8a272653SPeter Holm			die("sigaltstack get");
78*8a272653SPeter Holm
79*8a272653SPeter Holm		if (ss.ss_sp != NULL || ss.ss_flags != SS_DISABLE ||
80*8a272653SPeter Holm		    ss.ss_size != 0) {
81*8a272653SPeter Holm			fprintf(stderr, "invalid signal stack after execve: "
82*8a272653SPeter Holm			    "ss_sp=%p ss_size=%lu ss_flags=0x%x\n", ss.ss_sp,
83*8a272653SPeter Holm			    (unsigned long)ss.ss_size,
84*8a272653SPeter Holm			    (unsigned int)ss.ss_flags);
85*8a272653SPeter Holm			return 1;
86*8a272653SPeter Holm		}
87*8a272653SPeter Holm
88*8a272653SPeter Holm		printf("valid signal stack is valid after execve\n");
89*8a272653SPeter Holm
90*8a272653SPeter Holm		return 0;
91*8a272653SPeter Holm	}
92*8a272653SPeter Holm
93*8a272653SPeter Holm	// We have to use two threads to ensure that can detect the
94*8a272653SPeter Holm	// issue when new threads are added to the head (pre 269095)
95*8a272653SPeter Holm	// and the tail of the process thread list.
96*8a272653SPeter Holm	j = pthread_create(&tid1, NULL, thread_exec, NULL);
97*8a272653SPeter Holm	if (j != 0) {
98*8a272653SPeter Holm	       errno = j;
99*8a272653SPeter Holm	       die("pthread_create");
100*8a272653SPeter Holm	}
101*8a272653SPeter Holm
102*8a272653SPeter Holm	j = pthread_create(&tid2, NULL, thread_sleep, NULL);
103*8a272653SPeter Holm	if (j != 0) {
104*8a272653SPeter Holm	       errno = j;
105*8a272653SPeter Holm	       die("pthread_create");
106*8a272653SPeter Holm	}
107*8a272653SPeter Holm
108*8a272653SPeter Holm	j = pthread_join(tid1, NULL);
109*8a272653SPeter Holm	if (j != 0) {
110*8a272653SPeter Holm		errno = j;
111*8a272653SPeter Holm		die("pthread_join");
112*8a272653SPeter Holm	}
113*8a272653SPeter Holm
114*8a272653SPeter Holm	j = pthread_join(tid2, NULL);
115*8a272653SPeter Holm	if (j != 0) {
116*8a272653SPeter Holm		errno = j;
117*8a272653SPeter Holm	}
118*8a272653SPeter Holm
119*8a272653SPeter Holm	return 0;
120*8a272653SPeter Holm}
121*8a272653SPeter HolmEOF
122*8a272653SPeter Holm
123*8a272653SPeter Holmcc -o test-sigs -Wall -Wextra -O2 -g test-sigs.c -lpthread || exit 1
124*8a272653SPeter Holm./test-sigs
125*8a272653SPeter Holms=$?
126*8a272653SPeter Holm
127*8a272653SPeter Holmrm -f test-sigs test-sigs.c
128*8a272653SPeter Holmexit $s
129