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