2 * Stas Sergeev <stsp@users.sourceforge.net>
4 * test sigaltstack(SS_ONSTACK | SS_AUTODISARM)
5 * If that succeeds, then swapcontext() can be used inside sighandler safely.
20 #define SS_AUTODISARM (1 << 4)
23 static void *sstack, *ustack;
24 static ucontext_t uc, sc;
25 static const char *msg = "[OK]\tStack preserved";
26 static const char *msg2 = "[FAIL]\tStack corrupted";
32 void my_usr1(int sig, siginfo_t *si, void *u)
39 register unsigned long sp asm("sp");
41 if (sp < (unsigned long)sstack ||
42 sp >= (unsigned long)sstack + SIGSTKSZ) {
43 printf("[FAIL]\tSP is not on sigaltstack\n");
46 /* put some data on stack. other sighandler will try to overwrite it */
49 p = (struct stk_data *)(aa + 512);
52 printf("[RUN]\tsignal USR1\n");
53 err = sigaltstack(NULL, &stk);
55 perror("[FAIL]\tsigaltstack()");
58 if (stk.ss_flags != SS_DISABLE)
59 printf("[FAIL]\tss_flags=%i, should be SS_DISABLE\n",
62 printf("[OK]\tsigaltstack is disabled in sighandler\n");
63 swapcontext(&sc, &uc);
64 printf("%s\n", p->msg);
66 printf("[RUN]\tAborting\n");
71 void my_usr2(int sig, siginfo_t *si, void *u)
76 printf("[RUN]\tsignal USR2\n");
78 /* dont run valgrind on this */
79 /* try to find the data stored by previous sighandler */
80 p = memmem(aa, 1024, msg, strlen(msg));
82 printf("[FAIL]\tsigaltstack re-used\n");
83 /* corrupt the data */
85 /* tell other sighandler that his data is corrupted */
90 static void switch_fn(void)
92 printf("[RUN]\tswitched to user ctx\n");
103 sigemptyset(&act.sa_mask);
104 act.sa_flags = SA_ONSTACK | SA_SIGINFO;
105 act.sa_sigaction = my_usr1;
106 sigaction(SIGUSR1, &act, NULL);
107 act.sa_sigaction = my_usr2;
108 sigaction(SIGUSR2, &act, NULL);
109 sstack = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE,
110 MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
111 if (sstack == MAP_FAILED) {
116 stk.ss_size = SIGSTKSZ;
117 stk.ss_flags = SS_ONSTACK | SS_AUTODISARM;
118 err = sigaltstack(&stk, NULL);
120 perror("[FAIL]\tsigaltstack(SS_ONSTACK | SS_AUTODISARM)");
121 stk.ss_flags = SS_ONSTACK;
123 err = sigaltstack(&stk, NULL);
125 perror("[FAIL]\tsigaltstack(SS_ONSTACK)");
129 ustack = mmap(NULL, SIGSTKSZ, PROT_READ | PROT_WRITE,
130 MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0);
131 if (ustack == MAP_FAILED) {
137 uc.uc_stack.ss_sp = ustack;
138 uc.uc_stack.ss_size = SIGSTKSZ;
139 makecontext(&uc, switch_fn, 0);
142 err = sigaltstack(NULL, &stk);
144 perror("[FAIL]\tsigaltstack()");
147 if (stk.ss_flags != 0) {
148 printf("[FAIL]\tss_flags=%i, should be 0\n",
152 printf("[OK]\tsigaltstack is enabled after signal\n");
154 printf("[OK]\tTest passed\n");