summaryrefslogtreecommitdiffstats
path: root/shlibs
diff options
context:
space:
mode:
authorKarel Zak2009-10-01 15:14:48 +0200
committerKarel Zak2009-10-01 15:21:26 +0200
commit78419f261750efecfcde9a3b3c91b828821256ef (patch)
treef119c95f1ae5009a593f6c3bc46021135085406b /shlibs
parentmount: more verbose "mount: only root can do that" message (diff)
downloadkernel-qcow2-util-linux-78419f261750efecfcde9a3b3c91b828821256ef.tar.gz
kernel-qcow2-util-linux-78419f261750efecfcde9a3b3c91b828821256ef.tar.xz
kernel-qcow2-util-linux-78419f261750efecfcde9a3b3c91b828821256ef.zip
libblkid: fix non-magic FAT detection
On Wed, Sep 30, 2009 at 03:15:41PM +0200, Lawrence Rust wrote: > The problem is with shlibs/blkid/src/probers/vfat.c.  At the end of > this file the struct blkid_idinfo is declared with some magic > search strings.  In particular, 2 patterns are defined to match the > single byte jmp/jxx opcodes at the start of a DOS boot sector. > Because the partition was once formatted as a bootable DOS > partition it matches these patterns and consequently the function > probe_vfat is called.  For these simple pattern matches the function > probe_fat_nomagic is called to filter out false positives. > > In normal circumstances only MSDOS 2 and earlier floppies should be > detected by this function.  A very important feature of these disks > is the boot signature - bytes 0x55, 0xaa at the end of the 1st > sector which indicate to the BIOS that the disk is bootable.  All > MSDOS floppies have these bytes but the function probe_fat_nomagic > doesn't check for them. Note that the msdos/vfat superblock comments has been suggested by Lawrence. Reported-by: Lawrence Rust <lawrence@softsystem.co.uk> Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'shlibs')
-rw-r--r--shlibs/blkid/src/superblocks/vfat.c25
1 files changed, 18 insertions, 7 deletions
diff --git a/shlibs/blkid/src/superblocks/vfat.c b/shlibs/blkid/src/superblocks/vfat.c
index 9c20ebd9a..633e009e3 100644
--- a/shlibs/blkid/src/superblocks/vfat.c
+++ b/shlibs/blkid/src/superblocks/vfat.c
@@ -46,7 +46,7 @@ struct vfat_super_block {
/* 47*/ unsigned char vs_label[11];
/* 52*/ unsigned char vs_magic[8];
/* 5a*/ unsigned char vs_dummy2[164];
-/*1fe*/ unsigned char vs_pmagic[2];
+/* fe*/ unsigned char vs_pmagic[2];
};
/* Yucky misaligned values */
@@ -58,19 +58,21 @@ struct msdos_super_block {
/* 0e*/ uint16_t ms_reserved;
/* 10*/ uint8_t ms_fats;
/* 11*/ unsigned char ms_dir_entries[2];
-/* 13*/ unsigned char ms_sectors[2];
+/* 13*/ unsigned char ms_sectors[2]; /* =0 iff V3 or later */
/* 15*/ unsigned char ms_media;
-/* 16*/ uint16_t ms_fat_length;
+/* 16*/ uint16_t ms_fat_length; /* Sectors per FAT */
/* 18*/ uint16_t ms_secs_track;
/* 1a*/ uint16_t ms_heads;
/* 1c*/ uint32_t ms_hidden;
-/* 20*/ uint32_t ms_total_sect;
-/* 24*/ unsigned char ms_unknown[3];
+/* V3 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) */
/* 27*/ unsigned char ms_serno[4];
/* 2b*/ unsigned char ms_label[11];
/* 36*/ unsigned char ms_magic[8];
-/* 3d*/ unsigned char ms_dummy2[192];
-/*1fe*/ unsigned char ms_pmagic[2];
+/* 3e*/ unsigned char ms_dummy2[192];
+/* fe*/ unsigned char ms_pmagic[2];
};
struct vfat_dir_entry {
@@ -138,6 +140,15 @@ static unsigned char *search_fat_label(struct vfat_dir_entry *dir, int count)
static int probe_fat_nomagic(blkid_probe pr, const struct blkid_idmag *mag)
{
struct msdos_super_block *ms;
+ unsigned char *buf;
+
+ buf = blkid_probe_get_sector(pr, 0);
+ if (!buf)
+ return -1;
+
+ /* Old floppies have a valid MBR signature */
+ if (buf[510] != 0x55 || buf[511] != 0xAA)
+ return 1;
ms = blkid_probe_get_sb(pr, mag, struct msdos_super_block);
if (!ms)