sigaltstack() test program for i386

Melvin Smith (msmith@quix.robins.af.mil)
Fri, 24 May 1996 23:34:27 -0400 (EDT)


Try this without the sigaltstack() support, then use the previous
patch, and try again.

-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();
}