From: Pali Rohár Date: Mon, 5 Jul 2021 13:09:12 +0000 (+0200) Subject: libblkid: vfat: Fix reading FAT16 boot label and serial id X-Git-Tag: v2.38-rc1~372^2~1 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=575b559254a48751e916e8814b2c631335825705;p=thirdparty%2Futil-linux.git libblkid: vfat: Fix reading FAT16 boot label and serial id 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 --- diff --git a/libblkid/src/superblocks/vfat.c b/libblkid/src/superblocks/vfat.c index 9b23ea9008..72e9b78c6c 100644 --- a/libblkid/src/superblocks/vfat.c +++ b/libblkid/src/superblocks/vfat.c @@ -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"));