From: Robert Spalek Date: Thu, 24 Jun 2004 11:57:48 +0000 (+0000) Subject: - lizard_alloc() turns on the wrapper for SIGSEGV and lizard_free() restores X-Git-Tag: holmes-import~1038 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=4deb7fd75ea1306e943ab414efca26b1951cfd23;p=libucw.git - lizard_alloc() turns on the wrapper for SIGSEGV and lizard_free() restores its original value - lizard_decompress_safe() registers quickly the SIGSEGV handler using the wrapper. it saves 2 sys-calls. - allocate 3 more bytes for unaligned memory access --- diff --git a/lib/lizard-safe.c b/lib/lizard-safe.c index 6bba2544..6d0b10c9 100644 --- a/lib/lizard-safe.c +++ b/lib/lizard-safe.c @@ -22,12 +22,13 @@ struct lizard_buffer * lizard_alloc(uns max_len) { struct lizard_buffer *buf = xmalloc(sizeof(struct lizard_buffer)); - buf->len = ALIGN(max_len, PAGE_SIZE); + buf->len = ALIGN(max_len + 3, PAGE_SIZE); // +3 due to the unaligned access buf->start = mmap(NULL, buf->len + PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if (buf->start == MAP_FAILED) die("mmap(anonymous): %m"); if (mprotect(buf->start + buf->len, PAGE_SIZE, PROT_NONE) < 0) die("mprotect: %m"); + buf->old_sigsegv_handler = handle_signal(SIGSEGV); return buf; } @@ -35,12 +36,13 @@ void lizard_free(struct lizard_buffer *buf) { munmap(buf->start, buf->len + PAGE_SIZE); + signal(SIGSEGV, buf->old_sigsegv_handler); xfree(buf); } static jmp_buf safe_decompress_jump; static void -sigsegv_handler(int UNUSED whatsit) +sigsegv_handler(void) { log(L_ERROR, "SIGSEGV caught in lizard_decompress()"); longjmp(safe_decompress_jump, 1); @@ -59,7 +61,8 @@ lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length) errno = EFBIG; return -1; } - volatile sighandler_t old_handler = signal(SIGSEGV, sigsegv_handler); + volatile my_sighandler_t old_handler = signal_handler[SIGSEGV]; + signal_handler[SIGSEGV] = sigsegv_handler; int len, err; if (!setjmp(safe_decompress_jump)) { @@ -73,7 +76,7 @@ lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length) len = -1; err = EFAULT; } - signal(SIGSEGV, old_handler); + signal_handler[SIGSEGV] = old_handler; errno = err; return len; } diff --git a/lib/lizard.h b/lib/lizard.h index e84b5119..35200c08 100644 --- a/lib/lizard.h +++ b/lib/lizard.h @@ -31,6 +31,7 @@ int lizard_decompress(byte *in, byte *out); struct lizard_buffer { uns len; void *start, *ptr; + void *old_sigsegv_handler; }; struct lizard_buffer *lizard_alloc(uns max_len);