]> mj.ucw.cz Git - libucw.git/commitdiff
MJ's idea:
authorRobert Spalek <robert@ucw.cz>
Wed, 23 Jun 2004 16:48:25 +0000 (16:48 +0000)
committerRobert Spalek <robert@ucw.cz>
Wed, 23 Jun 2004 16:48:25 +0000 (16:48 +0000)
- only lock the memory by mprotect() once
- decompress into the middle of the buffer s.t. the barrier is at the distance
  as it used before
(needs adding one pointer to the structure)

lib/lizard-safe.c
lib/lizard.h

index c26a53bc7f92611ada03b40f93a217b685bbd162..c615acc4b131a704ee046cba9b3575dfa11dd13b 100644 (file)
@@ -22,17 +22,19 @@ struct lizard_buffer *
 lizard_alloc(uns max_len)
 {
   struct lizard_buffer *buf = xmalloc(sizeof(struct lizard_buffer));
-  buf->len = ALIGN(max_len + PAGE_SIZE, PAGE_SIZE);
-  buf->ptr = mmap(NULL, buf->len, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
-  if (buf->ptr == MAP_FAILED)
+  buf->len = ALIGN(max_len, PAGE_SIZE);
+  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");
   return buf;
 }
 
 void
 lizard_free(struct lizard_buffer *buf)
 {
-  munmap(buf->ptr, buf->len);
+  munmap(buf->start, buf->len + PAGE_SIZE);
   xfree(buf);
 }
 
@@ -51,27 +53,27 @@ lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length)
    * is caught in the case of buffer-overflow.  The function is not re-entrant
    * because of a static longjmp handler.  */
 {
-  volatile uns lock_offset = ALIGN(expected_length, PAGE_SIZE);
-  if (lock_offset + PAGE_SIZE > buf->len)
+  uns lock_offset = ALIGN(expected_length, PAGE_SIZE);
+  if (lock_offset > buf->len)
   {
     errno = EFBIG;
     return -1;
   }
-  mprotect(buf->ptr + lock_offset, PAGE_SIZE, PROT_NONE);
   volatile sighandler_t old_handler = signal(SIGSEGV, sigsegv_handler);
   int len, err;
   if (!setjmp(safe_decompress_jump))
   {
+    buf->ptr = buf->start + buf->len - lock_offset;
     len = lizard_decompress(in, buf->ptr);
     err = errno;
   }
   else
   {
+    buf->ptr = NULL;
     len = -1;
     err = EFAULT;
   }
   signal(SIGSEGV, old_handler);
-  mprotect(buf->ptr + lock_offset, PAGE_SIZE, PROT_READ | PROT_WRITE);
   errno = err;
   return len;
 }
index 52ddf8b397d9eeeb191b33504b15ad8a8c779151..e84b51193af19ecec2d2de06fd78b5a15e5aeb3a 100644 (file)
@@ -30,7 +30,7 @@ int lizard_decompress(byte *in, byte *out);
 /* lizard-safe.c */
 struct lizard_buffer {
   uns len;
-  void *ptr;
+  void *start, *ptr;
 };
 
 struct lizard_buffer *lizard_alloc(uns max_len);