|
@@ -166,6 +166,7 @@ invalid:
|
|
|
/**
|
|
|
* is_pmbr_valid(): test Protective MBR for validity
|
|
|
* @mbr: pointer to a legacy mbr structure
|
|
|
+ * @total_sectors: amount of sectors in the device
|
|
|
*
|
|
|
* Description: Checks for a valid protective or hybrid
|
|
|
* master boot record (MBR). The validity of a pMBR depends
|
|
@@ -180,9 +181,9 @@ invalid:
|
|
|
* Returns 0 upon invalid MBR, or GPT_MBR_PROTECTIVE or
|
|
|
* GPT_MBR_HYBRID depending on the device layout.
|
|
|
*/
|
|
|
-static int is_pmbr_valid(legacy_mbr *mbr)
|
|
|
+static int is_pmbr_valid(legacy_mbr *mbr, sector_t total_sectors)
|
|
|
{
|
|
|
- int i, ret = 0; /* invalid by default */
|
|
|
+ int i, part = 0, ret = 0; /* invalid by default */
|
|
|
|
|
|
if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
|
|
|
goto done;
|
|
@@ -190,6 +191,7 @@ static int is_pmbr_valid(legacy_mbr *mbr)
|
|
|
for (i = 0; i < 4; i++) {
|
|
|
ret = pmbr_part_valid(&mbr->partition_record[i]);
|
|
|
if (ret == GPT_MBR_PROTECTIVE) {
|
|
|
+ part = i;
|
|
|
/*
|
|
|
* Ok, we at least know that there's a protective MBR,
|
|
|
* now check if there are other partition types for
|
|
@@ -207,6 +209,18 @@ check_hybrid:
|
|
|
EFI_PMBR_OSTYPE_EFI_GPT) &&
|
|
|
(mbr->partition_record[i].os_type != 0x00))
|
|
|
ret = GPT_MBR_HYBRID;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Protective MBRs take up the lesser of the whole disk
|
|
|
+ * or 2 TiB (32bit LBA), ignoring the rest of the disk.
|
|
|
+ *
|
|
|
+ * Hybrid MBRs do not necessarily comply with this.
|
|
|
+ */
|
|
|
+ if (ret == GPT_MBR_PROTECTIVE) {
|
|
|
+ if (le32_to_cpu(mbr->partition_record[part].size_in_lba) !=
|
|
|
+ min((uint32_t) total_sectors - 1, 0xFFFFFFFF))
|
|
|
+ ret = 0;
|
|
|
+ }
|
|
|
done:
|
|
|
return ret;
|
|
|
}
|
|
@@ -568,6 +582,7 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
|
|
|
gpt_header *pgpt = NULL, *agpt = NULL;
|
|
|
gpt_entry *pptes = NULL, *aptes = NULL;
|
|
|
legacy_mbr *legacymbr;
|
|
|
+ sector_t total_sectors = i_size_read(state->bdev->bd_inode) >> 9;
|
|
|
u64 lastlba;
|
|
|
|
|
|
if (!ptes)
|
|
@@ -581,7 +596,7 @@ static int find_valid_gpt(struct parsed_partitions *state, gpt_header **gpt,
|
|
|
goto fail;
|
|
|
|
|
|
read_lba(state, 0, (u8 *)legacymbr, sizeof(*legacymbr));
|
|
|
- good_pmbr = is_pmbr_valid(legacymbr);
|
|
|
+ good_pmbr = is_pmbr_valid(legacymbr, total_sectors);
|
|
|
kfree(legacymbr);
|
|
|
|
|
|
if (!good_pmbr)
|