debug: Adapt fortify tests to libsupport
[glibc.git] / debug / tst-longjmp_chk2.c
blob7e1ee3edc591a399edd42e4f8058fbb62102f568
1 /* Verify longjmp fortify checking does not reject signal stacks. */
2 #include <assert.h>
3 #include <setjmp.h>
4 #include <signal.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8 #include <sys/types.h>
9 #include <sys/time.h>
10 #include <sys/resource.h>
11 #include <unistd.h>
13 #include <support/support.h>
15 static jmp_buf mainloop;
16 static sigset_t mainsigset;
17 static volatile sig_atomic_t pass;
19 static void
20 write_indented (const char *str)
22 for (int i = 0; i < pass; ++i)
23 write_message (" ");
24 write_message (str);
27 static void
28 stackoverflow_handler (int sig)
30 stack_t altstack;
31 /* Sanity check to keep test from looping forever (in case the longjmp
32 chk code is slightly broken). */
33 pass++;
34 sigaltstack (NULL, &altstack);
35 write_indented ("in signal handler\n");
36 if (altstack.ss_flags & SS_ONSTACK)
37 write_indented ("on alternate stack\n");
38 siglongjmp (mainloop, pass);
42 static volatile int *
43 recurse_1 (int n, volatile int *p)
45 if (n >= 0)
46 *recurse_1 (n + 1, p) += n;
47 return p;
51 static int
52 recurse (int n)
54 int sum = 0;
55 return *recurse_1 (n, &sum);
59 static int
60 do_test (void)
62 char mystack[SIGSTKSZ];
63 stack_t altstack;
64 struct sigaction action;
65 sigset_t emptyset;
66 /* Before starting the endless recursion, try to be friendly to the user's
67 machine. On some Linux 2.2.x systems, there is no stack limit for user
68 processes at all. We don't want to kill such systems. */
69 struct rlimit rl;
70 rl.rlim_cur = rl.rlim_max = 0x100000; /* 1 MB */
71 setrlimit (RLIMIT_STACK, &rl);
72 /* Install the alternate stack. */
73 altstack.ss_sp = mystack;
74 altstack.ss_size = sizeof (mystack);
75 altstack.ss_flags = 0; /* no SS_DISABLE */
76 if (sigaltstack (&altstack, NULL) < 0)
78 puts ("first sigaltstack failed");
79 return 0;
81 /* Install the SIGSEGV handler. */
82 sigemptyset (&action.sa_mask);
83 action.sa_handler = &stackoverflow_handler;
84 action.sa_flags = SA_ONSTACK;
85 sigaction (SIGSEGV, &action, (struct sigaction *) NULL);
86 sigaction (SIGBUS, &action, (struct sigaction *) NULL);
88 /* Save the current signal mask. */
89 sigemptyset (&emptyset);
90 sigprocmask (SIG_BLOCK, &emptyset, &mainsigset);
92 /* Provoke two stack overflows in a row. */
93 if (sigsetjmp (mainloop, 1) != 0)
95 assert (pass != 0);
96 printf ("%*sout of signal handler\n", pass, "");
98 else
99 assert (pass == 0);
101 sigaltstack (NULL, &altstack);
102 if (altstack.ss_flags & SS_ONSTACK)
103 printf ("%*son alternate stack\n", pass, "");
104 else
105 printf ("%*snot on alternate stack\n", pass, "");
107 if (pass < 2)
109 recurse (0);
110 puts ("recurse call returned");
111 return 2;
114 altstack.ss_flags |= SS_DISABLE;
115 if (sigaltstack (&altstack, NULL) == -1)
116 printf ("disabling alternate stack failed\n");
117 else
118 printf ("disabling alternate stack succeeded \n");
120 /* Restore the signal handlers, in case we trigger a crash after the
121 tests above. */
122 signal (SIGBUS, SIG_DFL);
123 signal (SIGSEGV, SIG_DFL);
125 return 0;
128 #include <support/test-driver.c>