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