]> mj.ucw.cz Git - libucw.git/blobdiff - lib/lizard-safe.c
big_alloc: check if big_alloc and big_free sizes match
[libucw.git] / lib / lizard-safe.c
index 40a5aa3daf3da7dfef3efc72fff04359320bd860..0473e34ae7270215267adb6b59e342eb43140485 100644 (file)
@@ -8,11 +8,10 @@
  */
 
 #include "lib/lib.h"
  */
 
 #include "lib/lib.h"
+#include "lib/threads.h"
 #include "lib/lizard.h"
 
 #include "lib/lizard.h"
 
-#include <stdlib.h>
 #include <sys/mman.h>
 #include <sys/mman.h>
-#include <sys/user.h>
 #include <fcntl.h>
 #include <signal.h>
 #include <setjmp.h>
 #include <fcntl.h>
 #include <signal.h>
 #include <setjmp.h>
@@ -21,7 +20,6 @@
 struct lizard_buffer {
   uns len;
   void *ptr;
 struct lizard_buffer {
   uns len;
   void *ptr;
-  struct sigaction old_sigsegv_handler;
 };
 
 struct lizard_buffer *
 };
 
 struct lizard_buffer *
@@ -30,22 +28,22 @@ lizard_alloc(void)
   struct lizard_buffer *buf = xmalloc(sizeof(struct lizard_buffer));
   buf->len = 0;
   buf->ptr = NULL;
   struct lizard_buffer *buf = xmalloc(sizeof(struct lizard_buffer));
   buf->len = 0;
   buf->ptr = NULL;
-  handle_signal(SIGSEGV, &buf->old_sigsegv_handler);
+  handle_signal(SIGSEGV);
   return buf;
 }
 
 void
 lizard_free(struct lizard_buffer *buf)
 {
   return buf;
 }
 
 void
 lizard_free(struct lizard_buffer *buf)
 {
+  unhandle_signal(SIGSEGV);
   if (buf->ptr)
   if (buf->ptr)
-    munmap(buf->ptr, buf->len + PAGE_SIZE);
-  unhandle_signal(SIGSEGV, &buf->old_sigsegv_handler);
+    munmap(buf->ptr, buf->len + CPU_PAGE_SIZE);
   xfree(buf);
 }
 
 static void
 lizard_realloc(struct lizard_buffer *buf, uns max_len)
   xfree(buf);
 }
 
 static void
 lizard_realloc(struct lizard_buffer *buf, uns max_len)
-  /* max_len needs to be aligned to PAGE_SIZE */
+  /* max_len needs to be aligned to CPU_PAGE_SIZE */
 {
   if (max_len <= buf->len)
     return;
 {
   if (max_len <= buf->len)
     return;
@@ -53,12 +51,12 @@ lizard_realloc(struct lizard_buffer *buf, uns max_len)
     max_len = 2*buf->len;
 
   if (buf->ptr)
     max_len = 2*buf->len;
 
   if (buf->ptr)
-    munmap(buf->ptr, buf->len + PAGE_SIZE);
+    munmap(buf->ptr, buf->len + CPU_PAGE_SIZE);
   buf->len = max_len;
   buf->len = max_len;
-  buf->ptr = mmap(NULL, buf->len + PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
+  buf->ptr = mmap(NULL, buf->len + CPU_PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
   if (buf->ptr == MAP_FAILED)
   if (buf->ptr == MAP_FAILED)
-    die("mmap(anonymous): %m");
-  if (mprotect(buf->ptr + buf->len, PAGE_SIZE, PROT_NONE) < 0)
+    die("mmap(anonymous, %d bytes): %m", (uns)(buf->len + CPU_PAGE_SIZE));
+  if (mprotect(buf->ptr + buf->len, CPU_PAGE_SIZE, PROT_NONE) < 0)
     die("mprotect: %m");
 }
 
     die("mprotect: %m");
 }
 
@@ -66,7 +64,6 @@ static jmp_buf safe_decompress_jump;
 static int
 sigsegv_handler(int signal UNUSED)
 {
 static int
 sigsegv_handler(int signal UNUSED)
 {
-  log(L_ERROR, "SIGSEGV caught in lizard_decompress()");
   longjmp(safe_decompress_jump, 1);
   return 1;
 }
   longjmp(safe_decompress_jump, 1);
   return 1;
 }
@@ -79,11 +76,10 @@ lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length)
    * case of buffer-overflow.  The function is not re-entrant because of a
    * static longjmp handler.  */
 {
    * case of buffer-overflow.  The function is not re-entrant because of a
    * static longjmp handler.  */
 {
-  uns lock_offset = ALIGN(expected_length + 3, PAGE_SIZE);     // +3 due to the unaligned access
+  uns lock_offset = ALIGN_TO(expected_length + 3, CPU_PAGE_SIZE);      // +3 due to the unaligned access
   if (lock_offset > buf->len)
     lizard_realloc(buf, lock_offset);
   if (lock_offset > buf->len)
     lizard_realloc(buf, lock_offset);
-  volatile sh_sighandler_t old_handler = signal_handler[SIGSEGV];
-  signal_handler[SIGSEGV] = sigsegv_handler;
+  volatile sh_sighandler_t old_handler = set_signal_handler(SIGSEGV, sigsegv_handler);
   byte *ptr;
   if (!setjmp(safe_decompress_jump))
   {
   byte *ptr;
   if (!setjmp(safe_decompress_jump))
   {
@@ -97,30 +93,10 @@ lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length)
   }
   else
   {
   }
   else
   {
+    log(L_ERROR, "SIGSEGV caught in lizard_decompress()");
     ptr = NULL;
     errno = EFAULT;
   }
     ptr = NULL;
     errno = EFAULT;
   }
-  signal_handler[SIGSEGV] = old_handler;
+  set_signal_handler(SIGSEGV, old_handler);
   return ptr;
 }
   return ptr;
 }
-
-#define BASE 65521 /* largest prime smaller than 65536 */
-
-inline uns
-update_adler32(uns adler, byte *ptr, uns len)
-  /* taken from RFC1950 */
-{
-  uns s1 = adler & 0xffff;
-  uns s2 = (adler >> 16) & 0xffff;
-  for (uns n = 0; n < len; n++) {
-    s1 = (s1 + ptr[n]) % BASE;
-    s2 = (s2 + s1)     % BASE;
-  }
-  return (s2 << 16) + s1;
-}
-
-uns
-adler32(byte *ptr, uns len)
-{
-  return update_adler32(1, ptr, len);
-}