summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
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