From 8d1675c114badee10e38db873cc71d08d8f0a492 Mon Sep 17 00:00:00 2001 From: Robert Spalek Date: Mon, 14 Jun 2004 17:13:14 +0000 Subject: [PATCH] added a wrapper for safe decompression (the page behind the decompression buffer is set READ-ONLY) --- lib/lizard.c | 39 +++++++++++++++++++++++++++++++++++++++ lib/lizard.h | 9 +++++++++ 2 files changed, 48 insertions(+) diff --git a/lib/lizard.c b/lib/lizard.c index d7b1b022..3968a710 100644 --- a/lib/lizard.c +++ b/lib/lizard.c @@ -11,6 +11,10 @@ #include "lib/lizard.h" #include +#include +#include +#include +#include typedef u16 hash_ptr_t; struct hash_record { @@ -394,6 +398,41 @@ perform_copy_command: return out - out_start; } +struct lizard_buffer * +lizard_alloc(uns max_len) +{ + int fd = open("/dev/zero", O_RDWR); + if (fd < 0) + die("open(/dev/zero): %m"); + struct lizard_buffer *buf = xmalloc(sizeof(struct lizard_buffer)); + buf->len = (max_len + 2*PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE; + buf->ptr = mmap(NULL, buf->len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (buf->ptr == MAP_FAILED) + die("mmap(/dev/zero): %m"); + return buf; +} + +void +lizard_free(struct lizard_buffer *buf) +{ + munmap(buf->ptr, buf->len); + xfree(buf); +} + +int +lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length) + /* Decompresses into buf->ptr and returns the length of the uncompressed + * file. Negative return values signalise errors. If something goes wrong + * and buffer would overflow, SIGSEGV is raised. */ +{ + uns lock_offset = (expected_length + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE; + if (lock_offset + PAGE_SIZE > buf->len) + return -1; + mprotect(buf->ptr, lock_offset, PROT_READ | PROT_WRITE); + mprotect(buf->ptr + lock_offset, PAGE_SIZE, PROT_READ); + return lizard_decompress(in, buf->ptr); +} + /* Description of the LZO1X format : diff --git a/lib/lizard.h b/lib/lizard.h index f46d0869..d0f8ba09 100644 --- a/lib/lizard.h +++ b/lib/lizard.h @@ -25,3 +25,12 @@ int lizard_compress(byte *in, uns in_len, byte *out); int lizard_decompress(byte *in, byte *out); + +struct lizard_buffer { + uns len; + void *ptr; +}; + +struct lizard_buffer *lizard_alloc(uns max_len); +void lizard_free(struct lizard_buffer *buf); +int lizard_decompress_safe(byte *in, struct lizard_buffer *buf, uns expected_length); -- 2.39.5