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