]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: dos: ignore exfat superblocks
authorThomas Weißschuh <thomas@t-8ch.de>
Sun, 20 Nov 2022 04:50:16 +0000 (05:50 +0100)
committerThomas Weißschuh <thomas@t-8ch.de>
Sun, 20 Nov 2022 22:07:33 +0000 (23:07 +0100)
libblkid/src/partitions/dos.c
libblkid/src/superblocks/exfat.c

index 6e758ecaaa28574a6130464418a498cba35559f9..5c7718c3e221db9aa32f165e60a2a91363708e35 100644 (file)
@@ -19,6 +19,8 @@
 
 /* see superblocks/vfat.c */
 extern int blkid_probe_is_vfat(blkid_probe pr);
+/* see superblocks/exfat.c */
+extern int blkid_probe_is_exfat(blkid_probe pr);
 
 static const struct dos_subtypes {
        unsigned char type;
@@ -218,7 +220,7 @@ static int probe_dos_pt(blkid_probe pr,
         * either the boot sector of a FAT filesystem or a DOS-type
         * partition table.
         */
-       if (blkid_probe_is_vfat(pr) == 1) {
+       if (blkid_probe_is_vfat(pr) == 1 || blkid_probe_is_exfat(pr) == 1) {
                DBG(LOWPROBE, ul_debug("probably FAT -- ignore"));
                goto nothing;
        }
index 4b6414fde9f9ed2f9bcb3ab44df74e9df02d275d..e760604908dc5ebae62257945709ad7ca91d4bc9 100644 (file)
@@ -158,26 +158,66 @@ static int exfat_validate_checksum(blkid_probe pr,
        return 1;
 }
 
-static int probe_exfat(blkid_probe pr, const struct blkid_idmag *mag)
+static int exfat_valid_superblock(blkid_probe pr, const struct exfat_super_block *sb)
 {
-       struct exfat_super_block *sb;
-       struct exfat_entry_label *label;
-
-       sb = blkid_probe_get_sb(pr, mag, struct exfat_super_block);
-       if (!sb || !CLUSTER_SIZE(sb))
-               return errno ? -errno : BLKID_PROBE_NONE;
-
        if (le16_to_cpu(sb->BootSignature) != 0xAA55)
-               return BLKID_PROBE_NONE;
+               return 0;
+
+       if (!CLUSTER_SIZE(sb))
+               return 0;
 
        if (memcmp(sb->JumpBoot, "\xEB\x76\x90", 3) != 0)
-               return BLKID_PROBE_NONE;
+               return 0;
 
        for (size_t i = 0; i < sizeof(sb->MustBeZero); i++)
                if (sb->MustBeZero[i] != 0x00)
-                       return BLKID_PROBE_NONE;
+                       return 0;
 
        if (!exfat_validate_checksum(pr, sb))
+               return 0;
+
+       return 1;
+}
+
+/* function prototype to avoid warnings (duplicate in partitions/dos.c) */
+extern int blkid_probe_is_exfat(blkid_probe pr);
+
+/*
+ * This function is used by MBR partition table parser to avoid
+ * misinterpretation of exFAT filesystem.
+ */
+int blkid_probe_is_exfat(blkid_probe pr)
+{
+       struct exfat_super_block *sb;
+       const struct blkid_idmag *mag = NULL;
+       int rc;
+
+       rc = blkid_probe_get_idmag(pr, &vfat_idinfo, NULL, &mag);
+       if (rc < 0)
+               return rc;      /* error */
+       if (rc != BLKID_PROBE_OK || !mag)
+               return 0;
+
+       sb = blkid_probe_get_sb(pr, mag, struct exfat_super_block);
+       if (!sb)
+               return 0;
+
+       if (memcmp(sb->FileSystemName, "EXFAT   ", 8) != 0)
+               return 0;
+
+       return exfat_valid_superblock(pr, sb);
+}
+
+static int probe_exfat(blkid_probe pr, const struct blkid_idmag *mag)
+{
+       struct exfat_super_block *sb;
+       struct exfat_entry_label *label;
+
+       sb = blkid_probe_get_sb(pr, mag, struct exfat_super_block);
+       if (!sb)
+               return errno ? -errno : BLKID_PROBE_NONE;
+
+       if (!exfat_valid_superblock(pr, sb))
                return BLKID_PROBE_NONE;
 
        label = find_label(pr, sb);