]> git.scottworley.com Git - nixos-qemu-vm-isolation/blob - modules/util-linux-squashfs-label.patch
9dd109e40abeb97a36adc74aa816e5cc4836dba9
[nixos-qemu-vm-isolation] / modules / util-linux-squashfs-label.patch
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 {
6 uint64_t export_table;
7 } __attribute__((packed));
8
9 +#define SQUASHFS_COMP_OPT_FLAG (1<<10)
10 +#define SQUASHFS_EXTRA_INFO_FLAG (1<<12)
11 +
12 +#define SQUASHFS_COMPRESSED_BIT (1<<15)
13 +#define SQUASHFS_METADATA_BLOCK_MAX 8192
14 +
15 +#define SQUASHFS_EXTRA_INFO_TAG_END 0
16 +#define SQUASHFS_EXTRA_INFO_TAG_LABEL 1
17 +#define SQUASHFS_EXTRA_INFO_TAG_UUID 2
18 +
19 +static const uint8_t *get_metadata_block(blkid_probe pr, uint64_t *pofs, uint16_t *pmetablock_len)
20 +{
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 */
26 + return NULL;
27 + }
28 + metablock_len &= ~SQUASHFS_COMPRESSED_BIT;
29 + if (metablock_len > SQUASHFS_METADATA_BLOCK_MAX) {
30 + return NULL;
31 + }
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;
36 + return buf;
37 +}
38 +
39 +static void probe_extra_info(blkid_probe pr, uint16_t flags)
40 +{
41 + uint64_t ofs = sizeof(struct sqsh_super_block);
42 + uint16_t metablock_len;
43 + const uint8_t *buf;
44 +
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);
48 + if (!buf) return;
49 + }
50 +
51 + /* extra_info comes next */
52 + buf = get_metadata_block(pr, &ofs, &metablock_len);
53 + if (!buf) return;
54 +
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)
59 + return;
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);
66 + }
67 + buf += len;
68 + }
69 +}
70 +
71 static int probe_squashfs(blkid_probe pr, const struct blkid_idmag *mag)
72 {
73 const struct sqsh_super_block *sq;
74 uint16_t vermaj;
75 uint16_t vermin;
76 + uint16_t flags;
77
78 sq = blkid_probe_get_sb(pr, mag, struct sqsh_super_block);
79 if (!sq)
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));
83
84 + flags = le16_to_cpu(sq->flags);
85 + if (flags & SQUASHFS_EXTRA_INFO_FLAG) {
86 + probe_extra_info(pr, flags);
87 + }
88 return 0;
89 }
90