aboutsummaryrefslogtreecommitdiff
path: root/lib/sqfs
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-05-04 15:32:52 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2019-05-04 22:22:48 +0200
commit2b975a449c17268f943403176a7609079b7af084 (patch)
treefee51e2f4b4f424c9a55dc35fb7aad21e3ce6580 /lib/sqfs
parent6f7ee71165b30272a4f18bca361c324c7671680c (diff)
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 <david.oberhollenzer@sigma-star.at>
Diffstat (limited to 'lib/sqfs')
-rw-r--r--lib/sqfs/frag_reader.c7
-rw-r--r--lib/sqfs/meta_reader.c8
-rw-r--r--lib/sqfs/meta_writer.c10
-rw-r--r--lib/sqfs/super.c4
4 files changed, 21 insertions, 8 deletions
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;
}