Skip to contentSkip to conversation

2.6.x signal handler bug

DISCUSSION Paul Maurides 4 participants 4 messages Jun 25, 2004 – Jun 28, 2004

lore
Share & tools
lore
#0 lore raw

The bug has been reproduced successfully using the following program on kernel 2.6.5 and 2.6.7, and probably affects any other 2.6 kernel.

Kernel 2.4 produce the correct behavior, an endless loop of handled signals, but on kernel 2.6 the program segfaults.

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

volatile int len;
volatile int real;
volatile int caught;
jmp_buf env;

void catcher(int sig){
signal(SIGSEGV,catcher); printf("requested: %9d malloced: %9d\n",len,real); longjmp(env, 1);
}

int main(){
char* p=0;
len = 0;
signal(SIGSEGV,catcher);

setjmp(env);
len++;
free(p);
p = malloc(len);
real = 0;

   while(1){
       p[real] = 0;
       real++;

}
return 0;
}

PS. I'm not subscribed to this list, so please include me in the cc

#1 lore raw
Quoted 6 lines · Paul Maurides
void catcher(int sig){
    signal(SIGSEGV,catcher);
    printf("requested: %9d malloced: %9d\n",len,real);
    longjmp(env, 1);
}

Use siglongjmp()

#2 lore raw
In reply to Paul Maurides

Neither printf() nor longjmp() are safe to call from within the sighandler. Have you tried deleting printf() and replacing longjmp() with siglongjmp()? This is a FAQ; search the list archives for details.

#3 lore raw
In reply to Paul Maurides
Quoted 3 lines · Paul Maurides

The bug has been reproduced successfully using the following program on kernel 2.6.5 and 2.6.7, and probably affects any other 2.6 kernel.

All, since about 2.5.71 or so.

Quoted 2 lines

Kernel 2.4 produce the correct behavior, an endless loop of handled signals, but on kernel 2.6 the program segfaults.

The program never returns from it's signal handler. Instead, it causes yet another segfault. Any program stupid enough to cause a segfault inside the segfault handler, should be killed. Full stop.

Quoted 16 lines

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

volatile int len;
volatile int real;
volatile int caught;
jmp_buf env;

void catcher(int sig){
   signal(SIGSEGV,catcher);
   printf("requested: %9d malloced: %9d\n",len,real);
   longjmp(env, 1);
}
Quoted 16 lines
int main(){
   char* p=0;
   len = 0;
   signal(SIGSEGV,catcher);

   setjmp(env);
   len++;
   free(p);
   p = malloc(len);
   real = 0;
   while(1){
       p[real] = 0;
       real++;
   }
   return 0;
}

Jörn

Signature · 3 lines
Fancy algorithms are buggier than simple ones, and they're much harder
to implement. Use simple algorithms as well as simple data structures.
-- Rob Pike