-Melvin
/*
* Test program to test sigaltstack() system call.
* Does a stack overflow, which normally linux/i386 will not be able
* to deliver. There are other ways of demonstrating but this is
* the easiest. Of course apply the sigaltstack() patch first or
* you wont see diddly.
*/
#include <sys/signal.h>
#include <asm/unistd.h>
#include <stdio.h>
#include <errno.h>
static inline _syscall2(int,sigaltstack, stack_t *, sa_in, stack_t *, sa_out )
struct sigaction act;
#define GET_STACK( x ) \
__asm__ __volatile("movl %%esp, %0\n\t" : "=q" (x) : :"%0" )
void handler()
{
unsigned long ss_sp;
printf( "Caught SIGSEGV and handled stack overflow correctly.\n" );
GET_STACK( ss_sp );
printf( "signal handler stack pointer = %p\n", ss_sp );
exit(0);
}
void recurse()
{
char buf[ 4096 ];
recurse();
}
int main()
{
long ret;
struct sigaltstack sa, sa_old;
unsigned long ss_sp;
/* Step 1 - setup your alternate sig-stack */
sa.ss_sp = malloc( MINSIGSTKSZ );
if( !sa.ss_sp )
printf( "malloc failed\n" );
sa.ss_size = MINSIGSTKSZ;
sa.ss_flags = 0;
if( sigaltstack( &sa, &sa_old ) < 0 ) {
printf( "failed to install alt-stack!\n" );
exit(0);
}
/* Step 2 - setup a sighandler and specify we want it delivered
* on the alternate stack */
act.sa_handler = handler;
act.sa_flags = SA_ONSTACK;
if( sigaction( SIGSEGV, &act, 0 ) < 0 ) {
printf( "failed to install sig-handler!\n" );
exit(0);
}
/* Step 3 - Generate a stack-overflow with recursion.
* Without the sigaltstack you will not handle the SIGSEGV
* because there will be no more space left on the processes
* main stack for the call.
* With the patch, you will catch it correctly! Wheee!!
*/
GET_STACK( ss_sp );
printf( "main stack pointer = %p\n", ss_sp );
recurse();
}