aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2021-06-25 14:12:26 +0200
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2021-06-25 17:37:56 +0200
commit3f887a1acc6129210d1ad4a484842bd411a85c7a (patch)
treeb1804d7e23512383de66e7e16fb75fc9cc10a44d
parentf09d9d3cbbb39f94fe9a43b0d90c370d33beafb2 (diff)
libsquashfs: get rid of potentially unaligned access and VLAs
The same problem with the meta data header again, 16 bit read from a buffer: copy the buffer data into a 16 bit variable instead of casting to something potentially unaligned. Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--lib/sqfs/comp/compressor.c29
-rw-r--r--lib/sqfs/meta_writer.c16
2 files changed, 33 insertions, 12 deletions
diff --git a/lib/sqfs/comp/compressor.c b/lib/sqfs/comp/compressor.c
index 42ee436..f079651 100644
--- a/lib/sqfs/comp/compressor.c
+++ b/lib/sqfs/comp/compressor.c
@@ -42,31 +42,44 @@ static const char *names[] = {
int sqfs_generic_write_options(sqfs_file_t *file, const void *data, size_t size)
{
- sqfs_u8 buffer[size + 2];
+ sqfs_u8 buffer[64];
+ sqfs_u16 header;
int ret;
- *((sqfs_u16 *)buffer) = htole16(0x8000 | size);
- memcpy(buffer + 2, data, size);
+ /* XXX: options for all known compressors should fit into this */
+ if (size >= (sizeof(buffer) - sizeof(header)))
+ return SQFS_ERROR_INTERNAL;
+
+ header = htole16(0x8000 | size);
+ memcpy(buffer, &header, sizeof(header));
+ memcpy(buffer + sizeof(header), data, size);
ret = file->write_at(file, sizeof(sqfs_super_t),
- buffer, sizeof(buffer));
+ buffer, sizeof(header) + size);
if (ret)
return ret;
- return sizeof(buffer);
+ return sizeof(header) + size;
}
int sqfs_generic_read_options(sqfs_file_t *file, void *data, size_t size)
{
- sqfs_u8 buffer[size + 2];
+ sqfs_u8 buffer[64];
+ sqfs_u16 header;
int ret;
+ /* XXX: options for all known compressors should fit into this */
+ if (size >= (sizeof(buffer) - sizeof(header)))
+ return SQFS_ERROR_INTERNAL;
+
ret = file->read_at(file, sizeof(sqfs_super_t),
- buffer, sizeof(buffer));
+ buffer, sizeof(header) + size);
if (ret)
return ret;
- if (le16toh(*((sqfs_u16 *)buffer)) != (0x8000 | size))
+ memcpy(&header, buffer, sizeof(header));
+
+ if (le16toh(header) != (0x8000 | size))
return SQFS_ERROR_CORRUPTED;
memcpy(data, buffer + 2, size);
diff --git a/lib/sqfs/meta_writer.c b/lib/sqfs/meta_writer.c
index 46a67cd..80f0fdd 100644
--- a/lib/sqfs/meta_writer.c
+++ b/lib/sqfs/meta_writer.c
@@ -49,8 +49,13 @@ struct sqfs_meta_writer_t {
static int write_block(sqfs_file_t *file, meta_block_t *outblk)
{
- size_t count = le16toh(((sqfs_u16 *)outblk->data)[0]) & 0x7FFF;
- sqfs_u64 off = file->get_size(file);
+ sqfs_u16 header;
+ size_t count;
+ sqfs_u64 off;
+
+ memcpy(&header, outblk->data, sizeof(header));
+ count = le16toh(header) & 0x7FFF;
+ off = file->get_size(file);
return file->write_at(file, off, outblk->data, count + 2);
}
@@ -92,6 +97,7 @@ sqfs_meta_writer_t *sqfs_meta_writer_create(sqfs_file_t *file,
int sqfs_meta_writer_flush(sqfs_meta_writer_t *m)
{
meta_block_t *outblk;
+ sqfs_u16 header;
sqfs_u32 count;
sqfs_s32 ret;
@@ -110,14 +116,16 @@ int sqfs_meta_writer_flush(sqfs_meta_writer_t *m)
}
if (ret > 0) {
- ((sqfs_u16 *)outblk->data)[0] = htole16(ret);
+ header = htole16(ret);
count = ret + 2;
} else {
- ((sqfs_u16 *)outblk->data)[0] = htole16(m->offset | 0x8000);
+ header = htole16(m->offset | 0x8000);
memcpy(outblk->data + 2, m->data, m->offset);
count = m->offset + 2;
}
+ memcpy(outblk->data, &header, sizeof(header));
+
ret = 0;
if (m->flags & SQFS_META_WRITER_KEEP_IN_MEMORY) {