Message ID | 1418428314-9611-1-git-send-email-srae@broadcom.com |
---|---|
State | Accepted |
Delegated to: | Łukasz Majewski |
Headers | show |
Hi Steve, > Signed-off-by: Steve Rae <srae@broadcom.com> > --- > > Changes in v4: > - move common code to static functions > > Changes in v3: None > Changes in v2: None > > disk/part_efi.c | 175 > +++++++++++++++++++++++++++++++++----------------------- 1 file > changed, 102 insertions(+), 73 deletions(-) > > diff --git a/disk/part_efi.c b/disk/part_efi.c > index efed58f..2c77f29 100644 > --- a/disk/part_efi.c > +++ b/disk/part_efi.c > @@ -69,6 +69,105 @@ static inline int is_bootable(gpt_entry *p) > sizeof(efi_guid_t)); > } > > +static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba, > + lbaint_t lastlba) > +{ > + uint32_t crc32_backup = 0; > + uint32_t calc_crc32; > + > + /* Check the GPT header signature */ > + if (le64_to_cpu(gpt_h->signature) != GPT_HEADER_SIGNATURE) { > + printf("%s signature is wrong: 0x%llX != 0x%llX\n", > + "GUID Partition Table Header", > + le64_to_cpu(gpt_h->signature), > + GPT_HEADER_SIGNATURE); > + return -1; > + } > + > + /* Check the GUID Partition Table CRC */ > + memcpy(&crc32_backup, &gpt_h->header_crc32, > sizeof(crc32_backup)); > + memset(&gpt_h->header_crc32, 0, sizeof(gpt_h->header_crc32)); > + > + calc_crc32 = efi_crc32((const unsigned char *)gpt_h, > + le32_to_cpu(gpt_h->header_size)); > + > + memcpy(&gpt_h->header_crc32, &crc32_backup, > sizeof(crc32_backup)); + > + if (calc_crc32 != le32_to_cpu(crc32_backup)) { > + printf("%s CRC is wrong: 0x%x != 0x%x\n", > + "GUID Partition Table Header", > + le32_to_cpu(crc32_backup), calc_crc32); > + return -1; > + } > + > + /* > + * Check that the my_lba entry points to the LBA that > contains the GPT > + */ > + if (le64_to_cpu(gpt_h->my_lba) != lba) { > + printf("GPT: my_lba incorrect: %llX != " LBAF "\n", > + le64_to_cpu(gpt_h->my_lba), > + lba); > + return -1; > + } > + > + /* > + * Check that the first_usable_lba and that the > last_usable_lba are > + * within the disk. > + */ > + if (le64_to_cpu(gpt_h->first_usable_lba) > lastlba) { > + printf("GPT: first_usable_lba incorrect: %llX > " > LBAF "\n", > + le64_to_cpu(gpt_h->first_usable_lba), > lastlba); > + return -1; > + } > + if (le64_to_cpu(gpt_h->last_usable_lba) > lastlba) { > + printf("GPT: last_usable_lba incorrect: %llX > " > LBAF "\n", > + le64_to_cpu(gpt_h->last_usable_lba), lastlba); > + return -1; > + } > + > + debug("GPT: first_usable_lba: %llX last_usable_lba: %llX > last lba: " > + LBAF "\n", le64_to_cpu(gpt_h->first_usable_lba), > + le64_to_cpu(gpt_h->last_usable_lba), lastlba); > + > + return 0; > +} > + > +static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e) > +{ > + uint32_t calc_crc32; > + > + /* Check the GUID Partition Table Entry Array CRC */ > + calc_crc32 = efi_crc32((const unsigned char *)gpt_e, > + le32_to_cpu(gpt_h->num_partition_entries) * > + le32_to_cpu(gpt_h->sizeof_partition_entry)); > + > + if (calc_crc32 != > le32_to_cpu(gpt_h->partition_entry_array_crc32)) { > + printf("%s: 0x%x != 0x%x\n", > + "GUID Partition Table Entry Array CRC is > wrong", > + > le32_to_cpu(gpt_h->partition_entry_array_crc32), > + calc_crc32); > + return -1; > + } > + > + return 0; > +} > + > +static void prepare_backup_gpt_header(gpt_header *gpt_h) > +{ > + uint32_t calc_crc32; > + uint64_t val; > + > + /* recalculate the values for the Backup GPT Header */ > + val = le64_to_cpu(gpt_h->my_lba); > + gpt_h->my_lba = gpt_h->alternate_lba; > + gpt_h->alternate_lba = cpu_to_le64(val); > + gpt_h->header_crc32 = 0; > + > + calc_crc32 = efi_crc32((const unsigned char *)gpt_h, > + le32_to_cpu(gpt_h->header_size)); > + gpt_h->header_crc32 = cpu_to_le32(calc_crc32); > +} > + > #ifdef CONFIG_EFI_PARTITION > /* > * Public Functions (include/part.h) > @@ -259,7 +358,6 @@ int write_gpt_table(block_dev_desc_t *dev_desc, > const int pte_blk_cnt = > BLOCK_CNT((gpt_h->num_partition_entries > * sizeof(gpt_entry)), > dev_desc); u32 calc_crc32; > - u64 val; > > debug("max lba: %x\n", (u32) dev_desc->lba); > /* Setup the Protective MBR */ > @@ -284,15 +382,7 @@ int write_gpt_table(block_dev_desc_t *dev_desc, > != pte_blk_cnt) > goto err; > > - /* recalculate the values for the Backup GPT Header */ > - val = le64_to_cpu(gpt_h->my_lba); > - gpt_h->my_lba = gpt_h->alternate_lba; > - gpt_h->alternate_lba = cpu_to_le64(val); > - gpt_h->header_crc32 = 0; > - > - calc_crc32 = efi_crc32((const unsigned char *)gpt_h, > - le32_to_cpu(gpt_h->header_size)); > - gpt_h->header_crc32 = cpu_to_le32(calc_crc32); > + prepare_backup_gpt_header(gpt_h); > > if (dev_desc->block_write(dev_desc->dev, > (lbaint_t)le64_to_cpu(gpt_h->last_usable_lba) > @@ -511,10 +601,6 @@ static int is_pmbr_valid(legacy_mbr * mbr) > static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba, > gpt_header *pgpt_head, gpt_entry **pgpt_pte) > { > - u32 crc32_backup = 0; > - u32 calc_crc32; > - u64 lastlba; > - > if (!dev_desc || !pgpt_head) { > printf("%s: Invalid Argument(s)\n", __func__); > return 0; > @@ -527,55 +613,8 @@ static int is_gpt_valid(block_dev_desc_t > *dev_desc, u64 lba, return 0; > } > > - /* Check the GPT header signature */ > - if (le64_to_cpu(pgpt_head->signature) != > GPT_HEADER_SIGNATURE) { > - printf("GUID Partition Table Header signature is > wrong:" > - "0x%llX != 0x%llX\n", > - le64_to_cpu(pgpt_head->signature), > - GPT_HEADER_SIGNATURE); > - return 0; > - } > - > - /* Check the GUID Partition Table CRC */ > - memcpy(&crc32_backup, &pgpt_head->header_crc32, > sizeof(crc32_backup)); > - memset(&pgpt_head->header_crc32, 0, > sizeof(pgpt_head->header_crc32)); - > - calc_crc32 = efi_crc32((const unsigned char *)pgpt_head, > - le32_to_cpu(pgpt_head->header_size)); > - > - memcpy(&pgpt_head->header_crc32, &crc32_backup, > sizeof(crc32_backup)); - > - if (calc_crc32 != le32_to_cpu(crc32_backup)) { > - printf("GUID Partition Table Header CRC is wrong:" > - "0x%x != 0x%x\n", > - le32_to_cpu(crc32_backup), calc_crc32); > - return 0; > - } > - > - /* Check that the my_lba entry points to the LBA that > contains the GPT */ > - if (le64_to_cpu(pgpt_head->my_lba) != lba) { > - printf("GPT: my_lba incorrect: %llX != %" PRIX64 > "\n", > - le64_to_cpu(pgpt_head->my_lba), > - lba); > + if (validate_gpt_header(pgpt_head, (lbaint_t)lba, > dev_desc->lba)) return 0; > - } > - > - /* Check the first_usable_lba and last_usable_lba are within > the disk. */ > - lastlba = (u64)dev_desc->lba; > - if (le64_to_cpu(pgpt_head->first_usable_lba) > lastlba) { > - printf("GPT: first_usable_lba incorrect: %llX > %" > PRIX64 "\n", > - le64_to_cpu(pgpt_head->first_usable_lba), > lastlba); > - return 0; > - } > - if (le64_to_cpu(pgpt_head->last_usable_lba) > lastlba) { > - printf("GPT: last_usable_lba incorrect: %llX > %" > PRIX64 "\n", > - le64_to_cpu(pgpt_head->last_usable_lba), > lastlba); > - return 0; > - } > - > - debug("GPT: first_usable_lba: %llX last_usable_lba %llX last > lba %" > - PRIX64 "\n", le64_to_cpu(pgpt_head->first_usable_lba), > - le64_to_cpu(pgpt_head->last_usable_lba), lastlba); > > /* Read and allocate Partition Table Entries */ > *pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head); > @@ -584,17 +623,7 @@ static int is_gpt_valid(block_dev_desc_t > *dev_desc, u64 lba, return 0; > } > > - /* Check the GUID Partition Table Entry Array CRC */ > - calc_crc32 = efi_crc32((const unsigned char *)*pgpt_pte, > - le32_to_cpu(pgpt_head->num_partition_entries) * > - le32_to_cpu(pgpt_head->sizeof_partition_entry)); > - > - if (calc_crc32 != > le32_to_cpu(pgpt_head->partition_entry_array_crc32)) { > - printf("GUID Partition Table Entry Array CRC is > wrong:" > - "0x%x != 0x%x\n", > - > le32_to_cpu(pgpt_head->partition_entry_array_crc32), > - calc_crc32); > - > + if (validate_gpt_entries(pgpt_head, *pgpt_pte)) { > free(*pgpt_pte); > return 0; > } Acked-by: Lukasz Majewski <l.majewski@samsung.com> Tested-by: Lukasz Majewski <l.majewski@samsung.com> Test HW: Exynos4412 - trats2 To Marek: This patch cleanly applies to master (SHA1:b9206e61f3d87535ac4f4b0b858e674fd1edfeaf) not u-boot-usb. Therefore I cannot apply it to u-boot-usb based -dfu tree. We can either wait up the moment when -dfu get in sync with mainline or apply this patch to mainline directly.
diff --git a/disk/part_efi.c b/disk/part_efi.c index efed58f..2c77f29 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -69,6 +69,105 @@ static inline int is_bootable(gpt_entry *p) sizeof(efi_guid_t)); } +static int validate_gpt_header(gpt_header *gpt_h, lbaint_t lba, + lbaint_t lastlba) +{ + uint32_t crc32_backup = 0; + uint32_t calc_crc32; + + /* Check the GPT header signature */ + if (le64_to_cpu(gpt_h->signature) != GPT_HEADER_SIGNATURE) { + printf("%s signature is wrong: 0x%llX != 0x%llX\n", + "GUID Partition Table Header", + le64_to_cpu(gpt_h->signature), + GPT_HEADER_SIGNATURE); + return -1; + } + + /* Check the GUID Partition Table CRC */ + memcpy(&crc32_backup, &gpt_h->header_crc32, sizeof(crc32_backup)); + memset(&gpt_h->header_crc32, 0, sizeof(gpt_h->header_crc32)); + + calc_crc32 = efi_crc32((const unsigned char *)gpt_h, + le32_to_cpu(gpt_h->header_size)); + + memcpy(&gpt_h->header_crc32, &crc32_backup, sizeof(crc32_backup)); + + if (calc_crc32 != le32_to_cpu(crc32_backup)) { + printf("%s CRC is wrong: 0x%x != 0x%x\n", + "GUID Partition Table Header", + le32_to_cpu(crc32_backup), calc_crc32); + return -1; + } + + /* + * Check that the my_lba entry points to the LBA that contains the GPT + */ + if (le64_to_cpu(gpt_h->my_lba) != lba) { + printf("GPT: my_lba incorrect: %llX != " LBAF "\n", + le64_to_cpu(gpt_h->my_lba), + lba); + return -1; + } + + /* + * Check that the first_usable_lba and that the last_usable_lba are + * within the disk. + */ + if (le64_to_cpu(gpt_h->first_usable_lba) > lastlba) { + printf("GPT: first_usable_lba incorrect: %llX > " LBAF "\n", + le64_to_cpu(gpt_h->first_usable_lba), lastlba); + return -1; + } + if (le64_to_cpu(gpt_h->last_usable_lba) > lastlba) { + printf("GPT: last_usable_lba incorrect: %llX > " LBAF "\n", + le64_to_cpu(gpt_h->last_usable_lba), lastlba); + return -1; + } + + debug("GPT: first_usable_lba: %llX last_usable_lba: %llX last lba: " + LBAF "\n", le64_to_cpu(gpt_h->first_usable_lba), + le64_to_cpu(gpt_h->last_usable_lba), lastlba); + + return 0; +} + +static int validate_gpt_entries(gpt_header *gpt_h, gpt_entry *gpt_e) +{ + uint32_t calc_crc32; + + /* Check the GUID Partition Table Entry Array CRC */ + calc_crc32 = efi_crc32((const unsigned char *)gpt_e, + le32_to_cpu(gpt_h->num_partition_entries) * + le32_to_cpu(gpt_h->sizeof_partition_entry)); + + if (calc_crc32 != le32_to_cpu(gpt_h->partition_entry_array_crc32)) { + printf("%s: 0x%x != 0x%x\n", + "GUID Partition Table Entry Array CRC is wrong", + le32_to_cpu(gpt_h->partition_entry_array_crc32), + calc_crc32); + return -1; + } + + return 0; +} + +static void prepare_backup_gpt_header(gpt_header *gpt_h) +{ + uint32_t calc_crc32; + uint64_t val; + + /* recalculate the values for the Backup GPT Header */ + val = le64_to_cpu(gpt_h->my_lba); + gpt_h->my_lba = gpt_h->alternate_lba; + gpt_h->alternate_lba = cpu_to_le64(val); + gpt_h->header_crc32 = 0; + + calc_crc32 = efi_crc32((const unsigned char *)gpt_h, + le32_to_cpu(gpt_h->header_size)); + gpt_h->header_crc32 = cpu_to_le32(calc_crc32); +} + #ifdef CONFIG_EFI_PARTITION /* * Public Functions (include/part.h) @@ -259,7 +358,6 @@ int write_gpt_table(block_dev_desc_t *dev_desc, const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries * sizeof(gpt_entry)), dev_desc); u32 calc_crc32; - u64 val; debug("max lba: %x\n", (u32) dev_desc->lba); /* Setup the Protective MBR */ @@ -284,15 +382,7 @@ int write_gpt_table(block_dev_desc_t *dev_desc, != pte_blk_cnt) goto err; - /* recalculate the values for the Backup GPT Header */ - val = le64_to_cpu(gpt_h->my_lba); - gpt_h->my_lba = gpt_h->alternate_lba; - gpt_h->alternate_lba = cpu_to_le64(val); - gpt_h->header_crc32 = 0; - - calc_crc32 = efi_crc32((const unsigned char *)gpt_h, - le32_to_cpu(gpt_h->header_size)); - gpt_h->header_crc32 = cpu_to_le32(calc_crc32); + prepare_backup_gpt_header(gpt_h); if (dev_desc->block_write(dev_desc->dev, (lbaint_t)le64_to_cpu(gpt_h->last_usable_lba) @@ -511,10 +601,6 @@ static int is_pmbr_valid(legacy_mbr * mbr) static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba, gpt_header *pgpt_head, gpt_entry **pgpt_pte) { - u32 crc32_backup = 0; - u32 calc_crc32; - u64 lastlba; - if (!dev_desc || !pgpt_head) { printf("%s: Invalid Argument(s)\n", __func__); return 0; @@ -527,55 +613,8 @@ static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba, return 0; } - /* Check the GPT header signature */ - if (le64_to_cpu(pgpt_head->signature) != GPT_HEADER_SIGNATURE) { - printf("GUID Partition Table Header signature is wrong:" - "0x%llX != 0x%llX\n", - le64_to_cpu(pgpt_head->signature), - GPT_HEADER_SIGNATURE); - return 0; - } - - /* Check the GUID Partition Table CRC */ - memcpy(&crc32_backup, &pgpt_head->header_crc32, sizeof(crc32_backup)); - memset(&pgpt_head->header_crc32, 0, sizeof(pgpt_head->header_crc32)); - - calc_crc32 = efi_crc32((const unsigned char *)pgpt_head, - le32_to_cpu(pgpt_head->header_size)); - - memcpy(&pgpt_head->header_crc32, &crc32_backup, sizeof(crc32_backup)); - - if (calc_crc32 != le32_to_cpu(crc32_backup)) { - printf("GUID Partition Table Header CRC is wrong:" - "0x%x != 0x%x\n", - le32_to_cpu(crc32_backup), calc_crc32); - return 0; - } - - /* Check that the my_lba entry points to the LBA that contains the GPT */ - if (le64_to_cpu(pgpt_head->my_lba) != lba) { - printf("GPT: my_lba incorrect: %llX != %" PRIX64 "\n", - le64_to_cpu(pgpt_head->my_lba), - lba); + if (validate_gpt_header(pgpt_head, (lbaint_t)lba, dev_desc->lba)) return 0; - } - - /* Check the first_usable_lba and last_usable_lba are within the disk. */ - lastlba = (u64)dev_desc->lba; - if (le64_to_cpu(pgpt_head->first_usable_lba) > lastlba) { - printf("GPT: first_usable_lba incorrect: %llX > %" PRIX64 "\n", - le64_to_cpu(pgpt_head->first_usable_lba), lastlba); - return 0; - } - if (le64_to_cpu(pgpt_head->last_usable_lba) > lastlba) { - printf("GPT: last_usable_lba incorrect: %llX > %" PRIX64 "\n", - le64_to_cpu(pgpt_head->last_usable_lba), lastlba); - return 0; - } - - debug("GPT: first_usable_lba: %llX last_usable_lba %llX last lba %" - PRIX64 "\n", le64_to_cpu(pgpt_head->first_usable_lba), - le64_to_cpu(pgpt_head->last_usable_lba), lastlba); /* Read and allocate Partition Table Entries */ *pgpt_pte = alloc_read_gpt_entries(dev_desc, pgpt_head); @@ -584,17 +623,7 @@ static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba, return 0; } - /* Check the GUID Partition Table Entry Array CRC */ - calc_crc32 = efi_crc32((const unsigned char *)*pgpt_pte, - le32_to_cpu(pgpt_head->num_partition_entries) * - le32_to_cpu(pgpt_head->sizeof_partition_entry)); - - if (calc_crc32 != le32_to_cpu(pgpt_head->partition_entry_array_crc32)) { - printf("GUID Partition Table Entry Array CRC is wrong:" - "0x%x != 0x%x\n", - le32_to_cpu(pgpt_head->partition_entry_array_crc32), - calc_crc32); - + if (validate_gpt_entries(pgpt_head, *pgpt_pte)) { free(*pgpt_pte); return 0; }
Signed-off-by: Steve Rae <srae@broadcom.com> --- Changes in v4: - move common code to static functions Changes in v3: None Changes in v2: None disk/part_efi.c | 175 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 102 insertions(+), 73 deletions(-)