]> git.sur5r.net Git - u-boot/blobdiff - disk/part_efi.c
imx_common: detect USB serial downloader reliably
[u-boot] / disk / part_efi.c
index fa95ce12329a7b4aafbcb859951d8f1976cefc2f..2973d52f6abb278756a814057e3b77d7c08945ca 100644 (file)
@@ -428,8 +428,9 @@ int write_gpt_table(struct blk_desc *dev_desc,
        return -1;
 }
 
-int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
-               disk_partition_t *partitions, int parts)
+int gpt_fill_pte(struct blk_desc *dev_desc,
+                gpt_header *gpt_h, gpt_entry *gpt_e,
+                disk_partition_t *partitions, int parts)
 {
        lbaint_t offset = (lbaint_t)le64_to_cpu(gpt_h->first_usable_lba);
        lbaint_t last_usable_lba = (lbaint_t)
@@ -444,24 +445,38 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e,
        char *str_type_guid;
        unsigned char *bin_type_guid;
 #endif
+       size_t hdr_start = gpt_h->my_lba;
+       size_t hdr_end = hdr_start + 1;
+
+       size_t pte_start = gpt_h->partition_entry_lba;
+       size_t pte_end = pte_start +
+               gpt_h->num_partition_entries * gpt_h->sizeof_partition_entry /
+               dev_desc->blksz;
 
        for (i = 0; i < parts; i++) {
                /* partition starting lba */
                lbaint_t start = partitions[i].start;
                lbaint_t size = partitions[i].size;
 
-               if (start && (start < offset)) {
-                       printf("Partition overlap\n");
-                       return -1;
-               }
-
                if (start) {
-                       gpt_e[i].starting_lba = cpu_to_le64(start);
                        offset = start + size;
                } else {
-                       gpt_e[i].starting_lba = cpu_to_le64(offset);
+                       start = offset;
                        offset += size;
                }
+
+               /*
+                * If our partition overlaps with either the GPT
+                * header, or the partition entry, reject it.
+                */
+               if (((start <= hdr_end && hdr_start <= (start + size)) ||
+                    (start <= pte_end && pte_start <= (start + size)))) {
+                       printf("Partition overlap\n");
+                       return -1;
+               }
+
+               gpt_e[i].starting_lba = cpu_to_le64(start);
+
                if (offset > (last_usable_lba + 1)) {
                        printf("Partitions layout exceds disk size\n");
                        return -1;
@@ -633,7 +648,7 @@ int gpt_restore(struct blk_desc *dev_desc, char *str_disk_guid,
                goto err;
 
        /* Generate partition entries */
-       ret = gpt_fill_pte(gpt_h, gpt_e, partitions, parts_count);
+       ret = gpt_fill_pte(dev_desc, gpt_h, gpt_e, partitions, parts_count);
        if (ret)
                goto err;