Partition parsing still mixed LBAs with hardcoded 512-byte sectors
all over the place.

Carry the block device logical block size through all read paths.

Assisted-by: Codex:gpt-5.5
Signed-off-by: Ahmad Fatoum <[email protected]>
---
 common/partitions.c     | 55 +++++++++++++++++++++++++++--------------
 common/partitions/dos.c |  4 +--
 common/partitions/efi.c | 21 ++++++----------
 include/partitions.h    |  2 +-
 4 files changed, 47 insertions(+), 35 deletions(-)

diff --git a/common/partitions.c b/common/partitions.c
index 8637b54b1708..617c2770eadf 100644
--- a/common/partitions.c
+++ b/common/partitions.c
@@ -36,10 +36,10 @@ static int register_one_partition(struct block_device *blk, 
struct partition *pa
        char *partition_name;
        int ret;
        struct cdev *cdev;
-       struct devfs_partition partinfo = {
-               .offset = part->first_sec * SECTOR_SIZE,
-               .size = part->size * SECTOR_SIZE,
-       };
+       struct devfs_partition partinfo = {};
+
+       partinfo.offset = part->first_sec * BLOCKSIZE(blk);
+       partinfo.size = part->size * BLOCKSIZE(blk);
 
        partition_name = xasprintf("%s.%d", blk->cdev.name, part->num);
 
@@ -92,24 +92,26 @@ static int remove_one_partition(struct block_device *blk, 
int no)
        return ret;
 }
 
-static struct partition_parser *partition_parser_get_by_filetype(uint8_t *buf)
+static struct partition_parser *partition_parser_get_by_filetype(uint8_t *buf,
+                                                                unsigned int 
blocksize)
 {
        enum filetype type;
        struct partition_parser *parser;
 
        /* first new partition table as EFI GPT */
-       type = file_detect_partition_table(buf, SECTOR_SIZE * 2, SECTOR_SIZE);
+       type = file_detect_partition_table(buf, blocksize * 2, blocksize);
 
        list_for_each_entry(parser, &partition_parser_list, list) {
                if (parser->type == type)
                        return parser;
        }
 
-       /* if not parser found search for old one
-        * so if EFI GPT not enable take it as MBR
-        * useful for compatibility
+       /* If no parser found search for old one, so if EFI GPT i
+        * not enabled, probe for MBR. useful for compatibility.
+        * 512 is hardcoded here as the MBR detection is not
+        * block-size dependent.
         */
-       type = file_detect_partition_table(buf, SECTOR_SIZE, SECTOR_SIZE);
+       type = file_detect_partition_table(buf, 512, 512);
        if (type == filetype_fat && !is_fat_boot_sector(buf))
                type = filetype_mbr;
 
@@ -150,9 +152,11 @@ struct partition_desc *partition_table_read(struct 
block_device *blk)
        struct partition_parser *parser;
        struct partition_desc *pdesc = NULL;
        uint8_t *buf;
+       unsigned int blocksize;
        int ret;
 
-       buf = malloc(2 * SECTOR_SIZE);
+       blocksize = BLOCKSIZE(blk);
+       buf = malloc(2 * blocksize);
 
        ret = block_read(blk, buf, 0, 2);
        if (ret != 0) {
@@ -160,7 +164,7 @@ struct partition_desc *partition_table_read(struct 
block_device *blk)
                goto err;
        }
 
-       parser = partition_parser_get_by_filetype(buf);
+       parser = partition_parser_get_by_filetype(buf, blocksize);
        if (!parser)
                goto err;
 
@@ -187,7 +191,7 @@ bool partition_is_free(struct partition_desc *pdesc, 
uint64_t start, uint64_t si
 {
        struct partition *p;
 
-       if (start < PARTITION_ALIGN_SECTORS)
+       if (start < partition_align_lba(pdesc->blk))
                return false;
 
        if (start + size >= pdesc->blk->num_blocks)
@@ -204,7 +208,7 @@ bool partition_is_free(struct partition_desc *pdesc, 
uint64_t start, uint64_t si
 int partition_find_free_space(struct partition_desc *pdesc, uint64_t sectors, 
uint64_t *start)
 {
        struct partition *p;
-       uint64_t align = PARTITION_ALIGN_SECTORS;
+       uint64_t align = partition_align_lba(pdesc->blk);
        uint64_t min_sec;
 
        min_sec = max(align, partition_first_usable_lba(pdesc->blk));
@@ -371,19 +375,25 @@ static int fuzz_partition_table_parser(struct 
block_device *ramdisk)
        struct partition *part;
        int rc = 0;
        struct partition_parser *parser;
-       u8 buf[2 * SECTOR_SIZE] __aligned(8);
+       u8 *buf;
+       unsigned int blocksize;
+
+       blocksize = BLOCKSIZE(ramdisk);
+       buf = malloc(2 * blocksize);
+       if (!buf)
+               return 0;
 
        rc = block_read(ramdisk, buf, 0, 2);
        if (rc != 0)
-               return 0;
+               goto out;
 
-       parser = partition_parser_get_by_filetype(buf);
+       parser = partition_parser_get_by_filetype(buf, blocksize);
        if (!parser)
-               return 0;
+               goto out;
 
        pdesc = parser->parse(buf, ramdisk);
        if (!pdesc)
-               return 0;
+               goto out;
 
        pdesc->parser = parser;
 
@@ -394,6 +404,8 @@ static int fuzz_partition_table_parser(struct block_device 
*ramdisk)
 
        partition_table_free(pdesc);
 
+out:
+       free(buf);
        return 0;
 }
 fuzz_test_ramdisk("partitions", fuzz_partition_table_parser);
@@ -430,6 +442,11 @@ sector_t partition_first_usable_lba(const struct 
block_device *blk)
        return blockdevice_round_nblocks(blk, first_partition_offset);
 }
 
+sector_t partition_align_lba(const struct block_device *blk)
+{
+       return blockdevice_round_nblocks(blk, PARTITION_ALIGN_SIZE);
+}
+
 static int set_first_partition_offset(struct param_d *p, void *priv)
 {
        if (first_partition_offset < MIN_SECTOR_SIZE) {
diff --git a/common/partitions/dos.c b/common/partitions/dos.c
index 1526b97dec67..e5286cb6eb1f 100644
--- a/common/partitions/dos.c
+++ b/common/partitions/dos.c
@@ -60,7 +60,7 @@ static inline int is_extended_partition(struct partition *p)
 
 static void *read_mbr(struct block_device *blk)
 {
-       void *buf = xmalloc(SECTOR_SIZE);
+       void *buf = xmalloc(BLOCKSIZE(blk));
        int ret;
 
        ret = block_read(blk, buf, 0, 1);
@@ -126,7 +126,7 @@ static int dos_get_disk_signature(struct param_d *p, void 
*_priv)
 static void dos_extended_partition(struct block_device *blk, struct 
dos_partition_desc *dpd,
                struct partition *partition, uint32_t signature)
 {
-       uint8_t *buf = xmalloc(SECTOR_SIZE);
+       uint8_t *buf = xmalloc(BLOCKSIZE(blk));
        uint32_t ebr_sector = partition->first_sec;
        struct partition_entry *table = (struct partition_entry *)&buf[0x1be];
        unsigned partno = 4;
diff --git a/common/partitions/efi.c b/common/partitions/efi.c
index 295c26a5a491..33d9a1df9e83 100644
--- a/common/partitions/efi.c
+++ b/common/partitions/efi.c
@@ -199,19 +199,20 @@ static gpt_entry *alloc_read_gpt_entries(struct 
block_device *blk,
 {
        u32 count = 0;
        gpt_entry *pte = NULL;
-       unsigned long from, size;
+       unsigned long from;
+       blkcnt_t size;
        int ret;
 
        count = compute_partitions_entries_size(pgpt_head);
        if (!count)
                return NULL;
 
-       pte = calloc(count, 1);
+       pte = calloc(blockdevice_round_block_nbytes(blk, count), 1);
        if (!pte)
                return NULL;
 
        from = le64_to_cpu(pgpt_head->partition_entry_lba);
-       size = count / GPT_BLOCK_SIZE;
+       size = blockdevice_round_nblocks(blk, count);
        ret = block_read(blk, pte, from, size);
        if (ret) {
                free(pte);
@@ -220,12 +221,6 @@ static gpt_entry *alloc_read_gpt_entries(struct 
block_device *blk,
        return pte;
 }
 
-static inline unsigned short bdev_logical_block_size(struct block_device
-*bdev)
-{
-       return SECTOR_SIZE;
-}
-
 /**
  * alloc_read_gpt_header(): Allocates GPT header, reads into it from disk
  * @state
@@ -239,7 +234,7 @@ static gpt_header *alloc_read_gpt_header(struct 
block_device *blk,
                                         u64 lba)
 {
        gpt_header *gpt;
-       unsigned ssz = bdev_logical_block_size(blk);
+       unsigned ssz = BLOCKSIZE(blk);
        int ret;
 
        gpt = calloc(ssz, 1);
@@ -286,7 +281,7 @@ static int is_gpt_valid(struct block_device *blk, u64 lba,
        }
 
        if (le32_to_cpu((*gpt)->header_size) < sizeof(struct _gpt_header) ||
-        le32_to_cpu((*gpt)->header_size) > bdev_logical_block_size(blk))
+           le32_to_cpu((*gpt)->header_size) > BLOCKSIZE(blk))
                goto fail;
 
        /* Check the GUID Partition Table CRC */
@@ -505,8 +500,8 @@ static int find_valid_gpt(struct efi_partition_desc *epd, 
void *buf)
        lastlba = last_lba(blk);
        if (force_gpt) {
                /* This will be added to the EFI Spec. per Intel after v1.02. */
-               if (file_detect_partition_table(buf, SECTOR_SIZE * 2,
-                                               SECTOR_SIZE) != filetype_gpt)
+               if (file_detect_partition_table(buf, 2 * BLOCKSIZE(blk),
+                                               BLOCKSIZE(blk)) != filetype_gpt)
                        goto fail;
        }
 
diff --git a/include/partitions.h b/include/partitions.h
index 398813eca58c..7eb8b1e6e228 100644
--- a/include/partitions.h
+++ b/include/partitions.h
@@ -58,7 +58,6 @@ struct partition_parser {
 };
 
 #define PARTITION_ALIGN_SIZE   SZ_1M
-#define PARTITION_ALIGN_SECTORS        (PARTITION_ALIGN_SIZE >> SECTOR_SHIFT)
 
 void partition_desc_init(struct partition_desc *pd, struct block_device *blk);
 int partition_parser_register(struct partition_parser *p);
@@ -72,5 +71,6 @@ void partition_table_free(struct partition_desc *pdesc);
 bool partition_is_free(struct partition_desc *pdesc, uint64_t start, uint64_t 
size);
 int partition_find_free_space(struct partition_desc *pdesc, uint64_t sectors, 
uint64_t *start);
 sector_t partition_first_usable_lba(const struct block_device *blk);
+sector_t partition_align_lba(const struct block_device *blk);
 
 #endif /* __PARTITIONS_PARSER_H__ */
-- 
2.47.3


Reply via email to