1 # From https://github.com/plougher/squashfs-tools/pull/264
2 diff --git a/libblkid/src/superblocks/squashfs.c b/libblkid/src/superblocks/squashfs.c
3 --- a/libblkid/src/superblocks/squashfs.c
4 +++ b/libblkid/src/superblocks/squashfs.c
5 @@ -38,11 +38,74 @@ struct sqsh_super_block {
7 } __attribute__((packed));
9 +#define SQUASHFS_COMP_OPT_FLAG (1<<10)
10 +#define SQUASHFS_EXTRA_INFO_FLAG (1<<12)
12 +#define SQUASHFS_COMPRESSED_BIT (1<<15)
13 +#define SQUASHFS_METADATA_BLOCK_MAX 8192
15 +#define SQUASHFS_EXTRA_INFO_TAG_END 0
16 +#define SQUASHFS_EXTRA_INFO_TAG_LABEL 1
17 +#define SQUASHFS_EXTRA_INFO_TAG_UUID 2
19 +static const uint8_t *get_metadata_block(blkid_probe pr, uint64_t *pofs, uint16_t *pmetablock_len)
21 + const uint8_t *buf = blkid_probe_get_buffer(pr, *pofs, 2);
22 + if (!buf) return NULL;
23 + uint16_t metablock_len = (buf[1]<<8) | buf[0];
24 + if (!(metablock_len & SQUASHFS_COMPRESSED_BIT)) {
25 + /* a compressed metadata block is not valid here */
28 + metablock_len &= ~SQUASHFS_COMPRESSED_BIT;
29 + if (metablock_len > SQUASHFS_METADATA_BLOCK_MAX) {
32 + buf = blkid_probe_get_buffer(pr, *pofs + 2, metablock_len);
33 + if (!buf) return NULL;
34 + *pmetablock_len = metablock_len;
35 + *pofs += 2 + metablock_len;
39 +static void probe_extra_info(blkid_probe pr, uint16_t flags)
41 + uint64_t ofs = sizeof(struct sqsh_super_block);
42 + uint16_t metablock_len;
45 + /* comp_opts, when present, comes right after the superblock */
46 + if (flags & SQUASHFS_COMP_OPT_FLAG) {
47 + buf = get_metadata_block(pr, &ofs, &metablock_len);
51 + /* extra_info comes next */
52 + buf = get_metadata_block(pr, &ofs, &metablock_len);
55 + const uint8_t *buf_end = buf + metablock_len;
56 + while (buf < buf_end) {
57 + unsigned char type = *buf++;
58 + if (type == SQUASHFS_EXTRA_INFO_TAG_END || buf >= buf_end)
60 + unsigned char len = *buf++;
61 + if (buf + len > buf_end) return;
62 + if (type == SQUASHFS_EXTRA_INFO_TAG_LABEL) {
63 + blkid_probe_set_label(pr, buf, len);
64 + } else if (type == SQUASHFS_EXTRA_INFO_TAG_UUID) {
65 + blkid_probe_set_uuid(pr, buf);
71 static int probe_squashfs(blkid_probe pr, const struct blkid_idmag *mag)
73 const struct sqsh_super_block *sq;
78 sq = blkid_probe_get_sb(pr, mag, struct sqsh_super_block);
80 @@ -58,6 +121,10 @@ static int probe_squashfs(blkid_probe pr, const struct blkid_idmag *mag)
81 blkid_probe_set_block_size(pr, le32_to_cpu(sq->block_size));
82 blkid_probe_set_fssize(pr, le64_to_cpu(sq->bytes_used));
84 + flags = le16_to_cpu(sq->flags);
85 + if (flags & SQUASHFS_EXTRA_INFO_FLAG) {
86 + probe_extra_info(pr, flags);