Skip to content

Commit

Permalink
partitions/efi: loosen check fot pmbr size in lba
Browse files Browse the repository at this point in the history
Matt found that commit 27a7c64 ("partitions/efi: account for pmbr
size in lba") caused his GPT formatted eMMC device not to boot.  The
reason is that this commit enforced Linux to always check the lesser of
the whole disk or 2Tib for the pMBR size in LBA.  While most disk
partitioning tools out there create a pMBR with these characteristics,
Microsoft does not, as it always sets the entry to the maximum 32-bit
limitation - even though a drive may be smaller than that[1].

Loosen this check and only verify that the size is either the whole disk
or 0xFFFFFFFF.  No tool in its right mind would set it to any value
other than these.

[1] http://thestarman.pcministry.com/asm/mbr/GPT.htm#GPTPT

Reported-and-tested-by: Matt Porter <[email protected]>
Signed-off-by: Davidlohr Bueso <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
Davidlohr Bueso authored and torvalds committed Sep 15, 2013
1 parent 3711d86 commit 6b02fa5
Showing 1 changed file with 6 additions and 2 deletions.
8 changes: 6 additions & 2 deletions block/partitions/efi.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ static inline int pmbr_part_valid(gpt_mbr_record *part)
*/
static int is_pmbr_valid(legacy_mbr *mbr, sector_t total_sectors)
{
uint32_t sz = 0;
int i, part = 0, ret = 0; /* invalid by default */

if (!mbr || le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
Expand Down Expand Up @@ -216,12 +217,15 @@ static int is_pmbr_valid(legacy_mbr *mbr, sector_t total_sectors)
/*
* Protective MBRs take up the lesser of the whole disk
* or 2 TiB (32bit LBA), ignoring the rest of the disk.
* Some partitioning programs, nonetheless, choose to set
* the size to the maximum 32-bit limitation, disregarding
* the disk size.
*
* 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))
sz = le32_to_cpu(mbr->partition_record[part].size_in_lba);
if (sz != (uint32_t) total_sectors - 1 && sz != 0xFFFFFFFF)
ret = 0;
}
done:
Expand Down

0 comments on commit 6b02fa5

Please sign in to comment.