summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2008-02-28 22:30:41 +0000
committermarcel <marcel@FreeBSD.org>2008-02-28 22:30:41 +0000
commitaa08e756e25b6a8d5d4eaaf6def143fdb69f758a (patch)
tree6f6e295a4fe6a03d9e080d77f59e03181bd1500a /sys/geom
parentc1cd98f4218d53ac138627299e2b59d0dfc43c07 (diff)
downloadFreeBSD-src-aa08e756e25b6a8d5d4eaaf6def143fdb69f758a.zip
FreeBSD-src-aa08e756e25b6a8d5d4eaaf6def143fdb69f758a.tar.gz
Better handle false positives. The MBR differs from the boot sector
only because there's a partition table where the boot sector has boot code. Boot sectors without boot code look like a MBR for all practical purposes. This change adds a check for the partition table and fails the probe when it's obvously invalid. The assumption being that the sector contains a boot sector and not a MBR. More checks are needed to distinguish a boot secto without boot code from a (empty) MBR.
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/part/g_part_mbr.c30
1 files changed, 24 insertions, 6 deletions
diff --git a/sys/geom/part/g_part_mbr.c b/sys/geom/part/g_part_mbr.c
index b096b33..9e6b56e 100644
--- a/sys/geom/part/g_part_mbr.c
+++ b/sys/geom/part/g_part_mbr.c
@@ -252,22 +252,42 @@ static int
g_part_mbr_probe(struct g_part_table *table, struct g_consumer *cp)
{
struct g_provider *pp;
- u_char *buf;
- int error, res;
+ u_char *buf, *p;
+ int error, index, res;
+ uint16_t magic;
pp = cp->provider;
/* Sanity-check the provider. */
if (pp->sectorsize < MBRSIZE || pp->mediasize < pp->sectorsize)
return (ENOSPC);
+ if (pp->sectorsize > 4096)
+ return (ENXIO);
/* Check that there's a MBR. */
buf = g_read_data(cp, 0L, pp->sectorsize, &error);
if (buf == NULL)
return (error);
- res = le16dec(buf + DOSMAGICOFFSET);
+
+ /* We goto out on mismatch. */
+ res = ENXIO;
+
+ magic = le16dec(buf + DOSMAGICOFFSET);
+ if (magic != DOSMAGIC)
+ goto out;
+
+ for (index = 0; index < NDOSPART; index++) {
+ p = buf + DOSPARTOFF + index * DOSPARTSIZE;
+ if (p[0] != 0 && p[0] != 0x80)
+ goto out;
+ }
+
+ /* Match. */
+ res = G_PART_PROBE_PRI_NORM;
+
+ out:
g_free(buf);
- return ((res == DOSMAGIC) ? G_PART_PROBE_PRI_NORM : ENXIO);
+ return (res);
}
static int
@@ -305,8 +325,6 @@ g_part_mbr_read(struct g_part_table *basetable, struct g_consumer *cp)
ent.dp_size = le32dec(p + 12);
if (ent.dp_typ == 0 || ent.dp_typ == DOSPTYP_PMBR)
continue;
- if (ent.dp_flag != 0 && ent.dp_flag != 0x80)
- continue;
if (ent.dp_start == 0 || ent.dp_size == 0)
continue;
sectors = ent.dp_esect & 0x3f;
OpenPOWER on IntegriCloud