Am 18. September 2026 14:13:51 MESZ schrieb Alexey Charkov 
<[email protected]>:
>Several GPT fields are read or written without converting to or from
>little-endian, which is wrong on big-endian hosts.
>
>gpt_fill_pte() takes my_lba and partition_entry_lba raw when working out
>the region a partition must not overlap, so on a big-endian host both
>bounds are byte-swapped garbage and the overlap check does not do
>anything useful.
>
>gpt_verify_partitions() compares the loop counter against
>num_partition_entries raw, so its "More partitions than allowed!" guard
>never triggers. It also swaps gpt_part_size, which is already in host
>order, having been computed from two le64_to_cpu() results a few lines
>above; drop that conversion rather than adding one. Left as it was, the
>size check on big-endian rejects a correct table with the memorable
>
>       Partition first size: 256 does not match 256!
>
>set_protective_mbr() stores the MBR signature and the protective
>partition's start_sect and nr_sects straight into __le16 and __le32
>fields. is_pmbr_valid() reads them back with le16_to_cpu() and
>get_unaligned_le32(), so on big-endian part_test_efi() rejects the table
>U-Boot has just written: 'part list' reports nothing and desc->part_type
>stays PART_TYPE_UNKNOWN. Linux and the UEFI specification expect the
>protective MBR little-endian too, so such a disk is useless everywhere.
>
>gpt_fill_pte() writes partition names as native efi_char16_t, but the
>specification stores them as UTF-16LE. The two readers here then
>disagree: print_efiname() takes the low byte of a native u16 and so
>matches what was written, while gpt_convert_efi_name_to_char() walks the
>raw bytes and follows the specification. gpt_verify_partitions() uses the
>latter, so on big-endian verifying a freshly written table fails with an
>empty name. Write the name little-endian and read it back the same way.
>
>All of this is a no-op on little-endian targets.
>
>Signed-off-by: Alexey Charkov <[email protected]>
>---
> disk/part_efi.c | 19 ++++++++++---------
> 1 file changed, 10 insertions(+), 9 deletions(-)
>
>diff --git a/disk/part_efi.c b/disk/part_efi.c
>index ede8bcddce1f..d8751297fbe9 100644
>--- a/disk/part_efi.c
>+++ b/disk/part_efi.c
>@@ -67,7 +67,7 @@ static char *print_efiname(gpt_entry *pte)
>       int i;
>       for (i = 0; i < PARTNAME_SZ; i++) {
>               u8 c;
>-              c = pte->partition_name[i] & 0xff;
>+              c = le16_to_cpu(pte->partition_name[i]) & 0xff;

Partition names are not restricted to ANSI characters. Please, convert to 
UTF-8. Look in charset.h for the right library function. Check if the library 
function works correctly on big-endian.

>               c = (c && !isprint(c)) ? '.' : c;
>               name[i] = c;
>       }
>@@ -377,10 +377,10 @@ static int set_protective_mbr(struct blk_desc *desc)
>                       MSDOS_MBR_BOOT_CODE_SIZE);
> 
>       /* Append signature */
>-      p_mbr->signature = MSDOS_MBR_SIGNATURE;
>+      p_mbr->signature = cpu_to_le16(MSDOS_MBR_SIGNATURE);
>       p_mbr->partition_record[0].sys_ind = EFI_PMBR_OSTYPE_EFI_GPT;
>-      p_mbr->partition_record[0].start_sect = 1;
>-      p_mbr->partition_record[0].nr_sects = (u32)desc->lba - 1;
>+      p_mbr->partition_record[0].start_sect = cpu_to_le32(1);
>+      p_mbr->partition_record[0].nr_sects = cpu_to_le32((u32)desc->lba - 1);
> 
>       /* Write MBR sector to the MMC device */
>       if (blk_dwrite(desc, 0, 1, p_mbr) != 1) {
>@@ -465,10 +465,10 @@ int gpt_fill_pte(struct blk_desc *desc,
>       char *str_type_guid;
>       unsigned char *bin_type_guid;
> #endif
>-      size_t hdr_start = gpt_h->my_lba;
>+      size_t hdr_start = le64_to_cpu(gpt_h->my_lba);
>       size_t hdr_end = hdr_start + 1;
> 
>-      size_t pte_start = gpt_h->partition_entry_lba;
>+      size_t pte_start = le64_to_cpu(gpt_h->partition_entry_lba);
>       size_t pte_end = pte_start + gpt_pte_blocks(desc, gpt_h);
> 
>       for (i = 0; i < parts; i++) {
>@@ -560,7 +560,8 @@ int gpt_fill_pte(struct blk_desc *desc,
> 
>               for (k = 0; k < min(dosname_len, efiname_len); k++)
>                       gpt_e[i].partition_name[k] =
>-                              (efi_char16_t)(partitions[i].name[k]);
>+                              cpu_to_le16((efi_char16_t)

UTF-8 should be converted to UTF-16 here using a library function.

Best regards

Heinrich

>+                                          (partitions[i].name[k]));
> 
>               debug("%s: name: %s offset[%d]: 0x" LBAF
>                     " size[%d]: 0x" LBAF "\n",
>@@ -854,7 +855,7 @@ int gpt_verify_partitions(struct blk_desc *desc,
>       gpt_e = *gpt_pte;
> 
>       for (i = 0; i < parts; i++) {
>-              if (i == gpt_head->num_partition_entries) {
>+              if (i == le32_to_cpu(gpt_head->num_partition_entries)) {
>                       pr_err("More partitions than allowed!\n");
>                       return -1;
>               }
>@@ -880,7 +881,7 @@ int gpt_verify_partitions(struct blk_desc *desc,
>                     (unsigned long long)gpt_part_size,
>                     (unsigned long long)partitions[i].size);
> 
>-              if (le64_to_cpu(gpt_part_size) != partitions[i].size) {
>+              if (gpt_part_size != partitions[i].size) {
>                       /* We do not check the extend partition size */
>                       if ((i == parts - 1) && (partitions[i].size == 0))
>                               continue;
>

Reply via email to