1 /* Verify longjmp fortify checking does not reject signal stacks. */
10 #include <sys/resource.h>
13 static int do_test (void);
14 #define TEST_FUNCTION do_test ()
15 #include "../test-skeleton.c"
17 static jmp_buf mainloop
;
18 static sigset_t mainsigset
;
19 static volatile sig_atomic_t pass
;
22 write_indented (const char *str
)
24 for (int i
= 0; i
< pass
; ++i
)
30 stackoverflow_handler (int sig
)
33 /* Sanity check to keep test from looping forever (in case the longjmp
34 chk code is slightly broken). */
36 sigaltstack (NULL
, &altstack
);
37 write_indented ("in signal handler\n");
38 if (altstack
.ss_flags
& SS_ONSTACK
)
39 write_indented ("on alternate stack\n");
40 siglongjmp (mainloop
, pass
);
45 recurse_1 (int n
, volatile int *p
)
48 *recurse_1 (n
+ 1, p
) += n
;
57 return *recurse_1 (n
, &sum
);
64 char mystack
[SIGSTKSZ
];
66 struct sigaction action
;
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. */
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)
80 puts ("first sigaltstack failed");
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
);
90 /* Save the current signal mask. */
91 sigemptyset (&emptyset
);
92 sigprocmask (SIG_BLOCK
, &emptyset
, &mainsigset
);
94 /* Provoke two stack overflows in a row. */
95 if (sigsetjmp (mainloop
, 1) != 0)
98 printf ("%*sout of signal handler\n", pass
, "");
103 sigaltstack (NULL
, &altstack
);
104 if (altstack
.ss_flags
& SS_ONSTACK
)
105 printf ("%*son alternate stack\n", pass
, "");
107 printf ("%*snot on alternate stack\n", pass
, "");
112 puts ("recurse call returned");
116 altstack
.ss_flags
|= SS_DISABLE
;
117 if (sigaltstack (&altstack
, NULL
) == -1)
118 printf ("disabling alternate stack failed\n");
120 printf ("disabling alternate stack succeeded \n");
122 /* Restore the signal handlers, in case we trigger a crash after the
124 signal (SIGBUS
, SIG_DFL
);
125 signal (SIGSEGV
, SIG_DFL
);