From 575b559254a48751e916e8814b2c631335825705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pali=20Roh=C3=A1r?= Date: Mon, 5 Jul 2021 15:09:12 +0200 Subject: [PATCH] libblkid: vfat: Fix reading FAT16 boot label and serial id MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- libblkid/src/superblocks/vfat.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/libblkid/src/superblocks/vfat.c b/libblkid/src/superblocks/vfat.c index 9b23ea900..72e9b78c6 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"));