]> git.ipfire.org Git - thirdparty/util-linux.git/blobdiff - libblkid/src/superblocks/exfat.c
libblkid: exfat: fix fail to find volume label
[thirdparty/util-linux.git] / libblkid / src / superblocks / exfat.c
index e760604908dc5ebae62257945709ad7ca91d4bc9..06ad5c8c02876a8c41a7003cf24b639bbfee6a27 100644 (file)
@@ -49,6 +49,8 @@ struct exfat_entry_label {
 #define EXFAT_ENTRY_EOD                0x00
 #define EXFAT_ENTRY_LABEL      0x83
 
+#define EXFAT_MAX_DIR_SIZE     (256 * 1024 * 1024)
+
 static uint64_t block_to_offset(const struct exfat_super_block *sb,
                uint64_t block)
 {
@@ -72,16 +74,17 @@ static uint64_t cluster_to_offset(const struct exfat_super_block *sb,
 static uint32_t next_cluster(blkid_probe pr,
                const struct exfat_super_block *sb, uint32_t cluster)
 {
-       uint32_t *next;
+       uint32_t *nextp, next;
        uint64_t fat_offset;
 
        fat_offset = block_to_offset(sb, le32_to_cpu(sb->FatOffset))
                + (uint64_t) cluster * sizeof(cluster);
-       next = (uint32_t *) blkid_probe_get_buffer(pr, fat_offset,
+       nextp = (uint32_t *) blkid_probe_get_buffer(pr, fat_offset,
                        sizeof(uint32_t));
-       if (!next)
+       if (!nextp)
                return 0;
-       return le32_to_cpu(*next);
+       memcpy(&next, nextp, sizeof(next));
+       return le32_to_cpu(next);
 }
 
 static struct exfat_entry_label *find_label(blkid_probe pr,
@@ -90,7 +93,7 @@ static struct exfat_entry_label *find_label(blkid_probe pr,
        uint32_t cluster = le32_to_cpu(sb->FirstClusterOfRootDirectory);
        uint64_t offset = cluster_to_offset(sb, cluster);
        uint8_t *entry;
-       const size_t max_iter = 10000;
+       const size_t max_iter = EXFAT_MAX_DIR_SIZE / EXFAT_ENTRY_SIZE;
        size_t i = 0;
 
        for (; i < max_iter; i++) {
@@ -118,7 +121,7 @@ static struct exfat_entry_label *find_label(blkid_probe pr,
 }
 
 /* From https://docs.microsoft.com/en-us/windows/win32/fileio/exfat-specification#34-main-and-backup-boot-checksum-sub-regions */
-static uint32_t exfat_boot_checksum(unsigned char *sectors,
+static uint32_t exfat_boot_checksum(const unsigned char *sectors,
                                    size_t sector_size)
 {
        uint32_t n_bytes = sector_size * 11;
@@ -140,7 +143,7 @@ static int exfat_validate_checksum(blkid_probe pr,
 {
        size_t sector_size = BLOCK_SIZE(sb);
        /* 11 sectors will be checksummed, the 12th contains the expected */
-       unsigned char *data = blkid_probe_get_buffer(pr, 0, sector_size * 12);
+       const unsigned char *data = blkid_probe_get_buffer(pr, 0, sector_size * 12);
        if (!data)
                return 0;