From: Robert Spalek Date: Mon, 14 Jun 2004 17:13:14 +0000 (+0000) Subject: added a wrapper for safe decompression (the page behind the decompression X-Git-Tag: holmes-import~1052 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=8d1675c114badee10e38db873cc71d08d8f0a492;p=libucw.git added a wrapper for safe decompression (the page behind the decompression buffer is set READ-ONLY) --- 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);