summaryrefslogtreecommitdiffstats
path: root/sys/geom
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2008-02-29 22:41:36 +0000
committermarcel <marcel@FreeBSD.org>2008-02-29 22:41:36 +0000
commit1c97028d69164abca37a0f85c3ec780c5415b654 (patch)
treeecc21a09e37b4cc8bb63283880421d8f47c69375 /sys/geom
parenta7d75a1a2ac7d7261da0c882d56c0854fe9cd364 (diff)
downloadFreeBSD-src-1c97028d69164abca37a0f85c3ec780c5415b654.zip
FreeBSD-src-1c97028d69164abca37a0f85c3ec780c5415b654.tar.gz
Follow-up improvements to the handling of false positives: If the
partition table is empty, check to see if we have something that looks sufficiently like a BPB. On non-i386 machines, the boot sector typically doesn't contain boot code; the end of the boot sector is all zeroes. This is also where the partition table is for MBRs. We only check the sector size and cluster size, as that seems to be the most reliable across implementations, BPB versions and platforms.
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/part/g_part_mbr.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/sys/geom/part/g_part_mbr.c b/sys/geom/part/g_part_mbr.c
index 9e6b56e..c12bf24 100644
--- a/sys/geom/part/g_part_mbr.c
+++ b/sys/geom/part/g_part_mbr.c
@@ -118,6 +118,24 @@ mbr_parse_type(const char *type, u_char *dp_typ)
return (EINVAL);
}
+static int
+mbr_probe_bpb(u_char *bpb)
+{
+ uint16_t secsz;
+ uint8_t clstsz;
+
+#define PO2(x) ((x & (x - 1)) == 0)
+ secsz = le16dec(bpb);
+ if (secsz < 512 || secsz > 4096 || !PO2(secsz))
+ return (0);
+ clstsz = bpb[2];
+ if (clstsz < 1 || clstsz > 128 || !PO2(clstsz))
+ return (0);
+#undef PO2
+
+ return (1);
+}
+
static void
mbr_set_chs(struct g_part_table *table, uint32_t lba, u_char *cylp, u_char *hdp,
u_char *secp)
@@ -253,7 +271,7 @@ g_part_mbr_probe(struct g_part_table *table, struct g_consumer *cp)
{
struct g_provider *pp;
u_char *buf, *p;
- int error, index, res;
+ int error, index, res, sum;
uint16_t magic;
pp = cp->provider;
@@ -282,8 +300,19 @@ g_part_mbr_probe(struct g_part_table *table, struct g_consumer *cp)
goto out;
}
- /* Match. */
- res = G_PART_PROBE_PRI_NORM;
+ /*
+ * If the partition table does not consist of all zeroes,
+ * assume we have a MBR. If it's all zeroes, we could have
+ * a boot sector. For example, a boot sector that doesn't
+ * have boot code -- common on non-i386 hardware. In that
+ * case we check if we have a possible BPB. If so, then we
+ * assume we have a boot sector instead.
+ */
+ sum = 0;
+ for (index = 0; index < NDOSPART * DOSPARTSIZE; index++)
+ sum += buf[DOSPARTOFF + index];
+ if (sum != 0 || !mbr_probe_bpb(buf + 0x0b))
+ res = G_PART_PROBE_PRI_NORM;
out:
g_free(buf);
OpenPOWER on IntegriCloud