]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
libblkid: vfat: Fix reading FAT16 boot label and serial id
authorPali Rohár <pali.rohar@gmail.com>
Mon, 5 Jul 2021 13:09:12 +0000 (15:09 +0200)
committerKarel Zak <kzak@redhat.com>
Tue, 20 Jul 2021 09:56:34 +0000 (11:56 +0200)
Older FAT16 variants do not have to contain boot label or serial id. Boot
sign 0x28 indicates that only serial id is present and boot sign 0x29
indicates that both boot label and serial id is present. Other boot sign
values (e.g. zero) indicates older FAT16 variant without boot label and
boot sign.

Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
libblkid/src/superblocks/vfat.c

index 9b23ea900828d79b4fa0728dbc1bf244fff8a7ab..72e9b78c6cbb0ce1c0886cf87cbfda152dddfac9 100644 (file)
@@ -53,6 +53,7 @@ struct vfat_super_block {
 
 /* Yucky misaligned values */
 struct msdos_super_block {
+/* DOS 2.0 BPB */
 /* 00*/        unsigned char   ms_ignored[3];
 /* 03*/        unsigned char   ms_sysid[8];
 /* 0b*/        unsigned char   ms_sector_size[2];
@@ -63,16 +64,21 @@ struct msdos_super_block {
 /* 13*/        unsigned char   ms_sectors[2]; /* =0 iff V3 or later */
 /* 15*/        unsigned char   ms_media;
 /* 16*/        uint16_t        ms_fat_length; /* Sectors per FAT */
+/* DOS 3.0 BPB */
 /* 18*/        uint16_t        ms_secs_track;
 /* 1a*/        uint16_t        ms_heads;
 /* 1c*/        uint32_t        ms_hidden;
-/* V3 BPB */
+/* DOS 3.31 BPB */
 /* 20*/        uint32_t        ms_total_sect; /* iff ms_sectors == 0 */
-/* V4 BPB */
-/* 24*/        unsigned char   ms_unknown[3]; /* Phys drive no., resvd, V4 sig (0x29) */
+/* DOS 3.4 EBPB */
+/* 24*/        unsigned char   ms_drive_number;
+/* 25*/        unsigned char   ms_boot_flags;
+/* 26*/        unsigned char   ms_ext_boot_sign; /* 0x28 - DOS 3.4 EBPB; 0x29 - DOS 4.0 EBPB */
 /* 27*/        unsigned char   ms_serno[4];
+/* DOS 4.0 EBPB */
 /* 2b*/        unsigned char   ms_label[11];
 /* 36*/        unsigned char   ms_magic[8];
+/* padding */
 /* 3e*/        unsigned char   ms_dummy2[0x1fe - 0x3e];
 /*1fe*/        unsigned char   ms_pmagic[2];
 } __attribute__((packed));
@@ -324,8 +330,11 @@ static int probe_vfat(blkid_probe pr, const struct blkid_idmag *mag)
                        vol_label = vol_label_buf;
                }
 
-               boot_label = ms->ms_label;
-               vol_serno = ms->ms_serno;
+               if (ms->ms_ext_boot_sign == 0x29)
+                       boot_label = ms->ms_label;
+
+               if (ms->ms_ext_boot_sign == 0x28 || ms->ms_ext_boot_sign == 0x29)
+                       vol_serno = ms->ms_serno;
 
                blkid_probe_set_value(pr, "SEC_TYPE", (unsigned char *) "msdos",
                               sizeof("msdos"));