summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorae <ae@FreeBSD.org>2010-12-28 08:36:44 +0000
committerae <ae@FreeBSD.org>2010-12-28 08:36:44 +0000
commit43a50d46ef733018d03e5a7057a0dbf61fbd559b (patch)
treeee524172ff44fd2abbeca41be08ee5b3736f7cdc
parent04373a011b12b5180ebb8a0de8062748f92f8c9c (diff)
downloadFreeBSD-src-43a50d46ef733018d03e5a7057a0dbf61fbd559b.zip
FreeBSD-src-43a50d46ef733018d03e5a7057a0dbf61fbd559b.tar.gz
Make EBR probe method less strictly to be able detect EBRs with
small non fatal inconsistency. EBR may contain boot loader and sometimes it just has some garbage data. Now this does not prevent FreeBSD to use extended partitions. But since we do not support bootcode for EBR we mark tables which have non empty boot area as corrupt. This does make them readonly and we can not damage this data. PR: kern/141235 MFC after: 1 month
-rw-r--r--sys/geom/part/g_part_ebr.c46
1 files changed, 25 insertions, 21 deletions
diff --git a/sys/geom/part/g_part_ebr.c b/sys/geom/part/g_part_ebr.c
index f16f42a..115162e 100644
--- a/sys/geom/part/g_part_ebr.c
+++ b/sys/geom/part/g_part_ebr.c
@@ -377,7 +377,7 @@ g_part_ebr_probe(struct g_part_table *table, struct g_consumer *cp)
char psn[8];
struct g_provider *pp;
u_char *buf, *p;
- int error, index, res, sum;
+ int error, index, res;
uint16_t magic;
pp = cp->provider;
@@ -409,29 +409,11 @@ g_part_ebr_probe(struct g_part_table *table, struct g_consumer *cp)
if (magic != DOSMAGIC)
goto out;
- /*
- * The sector is all zeroes, except for the partition entries,
- * pseudo boot code and some signatures or disk serial number.
- * The latter can be found in the 9 bytes immediately in front
- * of the partition table.
- */
- sum = 0;
- for (index = 96; index < DOSPARTOFF - 9; index++)
- sum += buf[index];
- if (sum != 0)
- goto out;
-
- for (index = 0; index < NDOSPART; index++) {
+ for (index = 0; index < 2; index++) {
p = buf + DOSPARTOFF + index * DOSPARTSIZE;
if (p[0] != 0 && p[0] != 0x80)
goto out;
- if (index < 2)
- continue;
- /* The 3rd & 4th entries are always zero. */
- if ((le64dec(p+0) + le64dec(p+8)) != 0)
- goto out;
}
-
res = G_PART_PROBE_PRI_NORM;
out:
@@ -450,7 +432,7 @@ g_part_ebr_read(struct g_part_table *basetable, struct g_consumer *cp)
u_char *buf;
off_t ofs, msize;
u_int lba;
- int error, index;
+ int error, index, sum;
pp = cp->provider;
table = (struct g_part_ebr_table *)basetable;
@@ -465,6 +447,28 @@ g_part_ebr_read(struct g_part_table *basetable, struct g_consumer *cp)
ebr_entry_decode(buf + DOSPARTOFF + 0 * DOSPARTSIZE, ent + 0);
ebr_entry_decode(buf + DOSPARTOFF + 1 * DOSPARTSIZE, ent + 1);
+
+ /* The 3rd & 4th entries should be zeroes. */
+ if (le64dec(buf + DOSPARTOFF + 2 * DOSPARTSIZE) +
+ le64dec(buf + DOSPARTOFF + 3 * DOSPARTSIZE) != 0) {
+ basetable->gpt_corrupt = 1;
+ printf("GEOM: %s: invalid entries in the EBR ignored.\n",
+ pp->name);
+ }
+ /* We do not support bootcode for EBR. If bootcode area is
+ * not zeroes, then mark this EBR as corrupt to do not break
+ * anything for another OS'es.
+ */
+ if (lba == 0) {
+ sum = 0;
+ for (index = 0; index < DOSPARTOFF; index++)
+ sum += buf[index];
+ if (sum != 0) {
+ basetable->gpt_corrupt = 1;
+ printf("GEOM: %s: EBR has non empty bootcode.\n",
+ pp->name);
+ }
+ }
g_free(buf);
if (ent[0].dp_typ == 0)
OpenPOWER on IntegriCloud