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.
This commit is contained in:
parent
a7d75a1a2a
commit
1c97028d69
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user