From 3f887a1acc6129210d1ad4a484842bd411a85c7a Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Fri, 25 Jun 2021 14:12:26 +0200 Subject: 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 --- lib/sqfs/comp/compressor.c | 29 +++++++++++++++++++++-------- lib/sqfs/meta_writer.c | 16 ++++++++++++---- 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) { -- cgit v1.2.3