From 2f87f626961ad529f3049561440395f84e5a8d13 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 13 Mar 2011 08:16:46 +1100 Subject: [PATCH] Make the tmp out buf slightly larger to account for incompressible data, and check for buffer overflows. --- lrzip.c | 6 +++++- lrzip_private.h | 3 ++- stream.c | 3 +++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/lrzip.c b/lrzip.c index 129933e..eb32d55 100644 --- a/lrzip.c +++ b/lrzip.c @@ -734,9 +734,13 @@ next_chunk: free(infilecopy); } +/* To perform STDOUT, we allocate a proportion of ram that is then used as + * a pseudo-temporary file */ static void open_tmpoutbuf(rzip_control *control) { - control->tmp_outbuf = malloc(control->maxram); + control->out_maxlen = control->maxram + control->page_size; + + control->tmp_outbuf = malloc(control->out_maxlen); if (unlikely(!control->tmp_outbuf)) fatal("Failed to malloc tmp_outbuf in open_tmpoutbuf\n"); control->out_ofs = control->out_len = MAGIC_LEN; diff --git a/lrzip_private.h b/lrzip_private.h index 6228385..2c7ebe7 100644 --- a/lrzip_private.h +++ b/lrzip_private.h @@ -162,7 +162,8 @@ struct rzip_control { char *tmp_outbuf; // Temporary file storage for stdout i64 out_ofs; // Output offset when tmp_outbuf in use i64 out_len; // Total length of tmp_outbuf - i64 rel_ofs; // Relative offset when stdou has been flushed + i64 out_maxlen; // The largest the tmp_outbuf can be used + i64 rel_ofs; // Relative tmp_outbuf offset when stdout has been flushed FILE *msgout; //stream for output messages const char *suffix; int compression_level; diff --git a/stream.c b/stream.c index a6899b2..7d11133 100644 --- a/stream.c +++ b/stream.c @@ -639,6 +639,9 @@ ssize_t put_fdout(rzip_control *control, int fd, void *offset_buf, ssize_t ret) { if (!STDOUT || DECOMPRESS || TEST_ONLY) return write(fd, offset_buf, (size_t)ret); + + if (unlikely(control->out_ofs + ret > control->out_maxlen)) + failure("Tried to write beyond temporary output buffer. Need a larger out_maxlen\n"); memcpy(control->tmp_outbuf + control->out_ofs, offset_buf, ret); control->out_ofs += ret; if (likely(control->out_ofs > control->out_len))