From 2b975a449c17268f943403176a7609079b7af084 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Sat, 4 May 2019 15:32:52 +0200 Subject: Remove compressor internal buffers Pass in an external destination buffer + size and allow for propper bounds checking (especially when unpacking). Signed-off-by: David Oberhollenzer --- lib/sqfs/frag_reader.c | 7 +++++-- lib/sqfs/meta_reader.c | 8 +++++++- lib/sqfs/meta_writer.c | 10 +++++++--- lib/sqfs/super.c | 4 ++-- 4 files changed, 21 insertions(+), 8 deletions(-) (limited to 'lib/sqfs') diff --git a/lib/sqfs/frag_reader.c b/lib/sqfs/frag_reader.c index 1906376..74fd292 100644 --- a/lib/sqfs/frag_reader.c +++ b/lib/sqfs/frag_reader.c @@ -42,12 +42,15 @@ static int precache_block(frag_reader_t *f, size_t i) } if (compressed) { - ret = f->cmp->do_block(f->cmp, f->buffer, size); + ret = f->cmp->do_block(f->cmp, f->buffer, size, + f->buffer + f->block_size, f->block_size); if (ret <= 0) { fputs("extracting fragment failed\n", stderr); return -1; } + + memmove(f->buffer, f->buffer + f->block_size, ret); } f->current_index = i; @@ -73,7 +76,7 @@ frag_reader_t *frag_reader_create(sqfs_super_t *super, int fd, ++blockcount; /* pre allocate all the stuff */ - f = calloc(1, sizeof(*f) + super->block_size); + f = calloc(1, sizeof(*f) + super->block_size * 2); if (f == NULL) goto fail_rd; diff --git a/lib/sqfs/meta_reader.c b/lib/sqfs/meta_reader.c index 8cd7c8f..1a70238 100644 --- a/lib/sqfs/meta_reader.c +++ b/lib/sqfs/meta_reader.c @@ -79,12 +79,18 @@ int meta_reader_seek(meta_reader_t *m, uint64_t block_start, size_t offset) goto fail_trunc; if (compressed) { - ret = m->cmp->do_block(m->cmp, m->data, size); + ret = m->cmp->do_block(m->cmp, m->data, size, + m->scratch, sizeof(m->scratch)); if (ret <= 0) { fputs("error uncompressing meta data block\n", stderr); return -1; } + + memcpy(m->data, m->scratch, ret); + + if ((size_t)ret < sizeof(m->data)) + memset(m->data + ret, 0, sizeof(m->data) - ret); } return 0; diff --git a/lib/sqfs/meta_writer.c b/lib/sqfs/meta_writer.c index 95092d5..77ceeb9 100644 --- a/lib/sqfs/meta_writer.c +++ b/lib/sqfs/meta_writer.c @@ -30,23 +30,27 @@ void meta_writer_destroy(meta_writer_t *m) int meta_writer_flush(meta_writer_t *m) { ssize_t ret, count; + void *ptr; if (m->offset == 0) return 0; - ret = m->cmp->do_block(m->cmp, m->data + 2, m->offset); + ret = m->cmp->do_block(m->cmp, m->data + 2, m->offset, + m->scratch + 2, sizeof(m->scratch) - 2); if (ret < 0) return -1; if (ret > 0) { - ((uint16_t *)m->data)[0] = htole16(ret); + ((uint16_t *)m->scratch)[0] = htole16(ret); count = ret + 2; + ptr = m->scratch; } else { ((uint16_t *)m->data)[0] = htole16(m->offset | 0x8000); count = m->offset + 2; + ptr = m->data; } - ret = write_retry(m->outfd, m->data, count); + ret = write_retry(m->outfd, ptr, count); if (ret < 0) { perror("writing meta data"); diff --git a/lib/sqfs/super.c b/lib/sqfs/super.c index b402496..d3b79c6 100644 --- a/lib/sqfs/super.c +++ b/lib/sqfs/super.c @@ -17,8 +17,8 @@ int sqfs_super_init(sqfs_super_t *super, size_t block_size, uint32_t mtime, return -1; } - if (block_size < 8192 || block_size >= (1 << 24)) { - fputs("Block size must be between 8k and 1M\n", stderr); + if (block_size < 4096 || block_size >= (1 << 24)) { + fputs("Block size must be between 4k and 1M\n", stderr); return -1; } -- cgit v1.2.3