2.2.1: memory corruption and SIGSEGV handlers.

Tigran Aivazian (tigran@SCO.com)
Mon, 1 Mar 1999 15:44:49 +0000 (GMT)


Hi guys,

Below is a simple program that does this:

1. Registers a handler for SIGSEGV using sigaction(2) with no special
flags.

2. Causes the first SIGSEGV to be sent by *(int *)0 = 0;

3. Inside the handler prints something and does *(int *)0 = 0;

This results in a recursive invocation of the handler, which is
reasonable.

However, there are two problems I personally see here:

a) eventually, the program hangs (presumably when we run out of user
stack)

b) if you, additionally do something like ulimit -sH 1 before running the
program, it causes some memory (page cache?) corruption (i.e. next time
you run gcc(1) to compile something you get Internal error: signal 11
stuff).

This is clearly wrong so someone should have a look at the different code
paths corresponding to signal delivery in the case of kill(2) and via GP
fault (trap handler). (i.e. if I replace *0 = 0 with kill(getpid(),
SIGSEGV) everything is ok).

Regards,
------
Tigran A. Aivazian | http://www.sco.com
Escalations Research Group | tel: +44-(0)1923-813796
Santa Cruz Operation Ltd | http://www.aivazian.demon.co.uk

#include <stdio.h>
#include <signal.h>
#include <unistd.h>

int sig = SIGSEGV;

void gotsig(int signo)
{
int stack;
fprintf(stderr, "%d: signal%d (stack=%p) ",
getpid(), signo, &stack);
*(int *)0 = 0;
}

int main(int argc, char *argv[])
{
struct sigaction act;
act.sa_handler = gotsig;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
if ( -1 == sigaction(sig, &act, NULL)) {
perror("sigaction()");
exit(1);
}
*(int *)0 = 0;
return 0;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/