Am 1. November 2026 08:02:50 MEZ schrieb Ana Bobillo <[email protected]>:
>From: Ana Bobillo <[email protected]>
>
>part_get_info_extended() makes up the UUID of a DOS partition as
>"%08x-%02x" from the disk signature and the partition number, into a
>buffer of 12 bytes. That is enough up to partition 255, but
>MAX_EXT_PARTS lets the number reach 256, whose three digits make
>sprintf() write the terminating NUL past the end of the buffer.
>
>Size the buffer like the UUID it is copied into, and use snprintf().
>
>Add a test with 256 partitions, which catches the overflow on sandbox
>with CONFIG_ASAN.
>
>Signed-off-by: Ana Bobillo <[email protected]>
>Reviewed-by: Simon Glass <[email protected]>
>---
>(no changes since v1)
>
> disk/part_dos.c |  6 ++++--
> test/dm/part.c  | 46 ++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 50 insertions(+), 2 deletions(-)
>
>diff --git a/disk/part_dos.c b/disk/part_dos.c
>index bc40d9d2829..3029ee0c31a 100644
>--- a/disk/part_dos.c
>+++ b/disk/part_dos.c
>@@ -325,9 +325,11 @@ static int part_get_info_extended(struct blk_desc *desc,
>                                                "0x%x", pt->sys_ind);
>                                       info->bootable = get_bootable(pt);
>                                       if (CONFIG_IS_ENABLED(PARTITION_UUIDS)) 
> {
>-                                              char str[12];
>+                                              /* part_num may take three 
>digits */
>+                                              char str[UUID_STR_LEN + 1];
> 
>-                                              sprintf(str, "%08x-%02x", 
>disksig, part_num);
>+                                              snprintf(str, sizeof(str), 
>"%08x-%02x",
>+                                                       disksig, part_num);
>                                               disk_partition_set_uuid(info, 
> str);
>                                       }
>                                       info->sys_ind = pt->sys_ind;
>diff --git a/test/dm/part.c b/test/dm/part.c
>index 4938d962144..f8a0fa974c1 100644
>--- a/test/dm/part.c
>+++ b/test/dm/part.c
>@@ -423,3 +423,49 @@ static int dm_test_part_dos_ext_empty(struct 
>unit_test_state *uts)
>       return 0;
> }
> DM_TEST(dm_test_part_dos_ext_empty, UTF_SCAN_PDATA | UTF_SCAN_FDT | 
> UTF_CONSOLE);
>+
>+/*
>+ * Partition numbers above 255 take three digits in the UUID made up for a
>+ * DOS partition, from the disk signature and the partition number
>+ */
>+static int dm_test_part_dos_uuid(struct unit_test_state *uts)
>+{
>+      struct disk_partition info;
>+      dos_partition_t pt[4];
>+      struct blk_desc *desc;
>+      int part;
>+
>+      if (!CONFIG_IS_ENABLED(PARTITION_UUIDS))
>+              return -EAGAIN;
>+
>+      ut_asserteq(2, blk_get_device_by_str("mmc", "2", &desc));
>+      ut_asserteq(512, desc->blksz);
>+
>+      /* an extended partition from sector 2 */
>+      memset(pt, '\0', sizeof(pt));
>+      dos_set_entry(&pt[0], DOS_PART_TYPE_EXTENDED, 2, 512);
>+      ut_assertok(dos_write_table(desc, 0, pt));
>+
>+      /*
>+       * holding logical partitions 5 to 256, each of one sector after its
>+       * table, with the tables two sectors apart from sector 2 on
>+       */
>+      for (part = 5; part <= 256; part++) {
>+              memset(pt, '\0', sizeof(pt));
>+              dos_set_entry(&pt[0], 0x83, 1, 1);
>+              if (part < 256)
>+                      dos_set_entry(&pt[1], DOS_PART_TYPE_EXTENDED,
>+                                    (part - 4) * 2, 2);
>+              ut_assertok(dos_write_table(desc, 2 + (part - 5) * 2, pt));
>+      }
>+
>+      ut_assertok(part_get_info_by_type(desc, 255, PART_TYPE_DOS, &info));
>+      ut_asserteq(2 + 250 * 2 + 1, info.start);
>+      ut_asserteq_str("00000000-ff", disk_partition_uuid(&info));
>+      ut_assertok(part_get_info_by_type(desc, 256, PART_TYPE_DOS, &info));
>+      ut_asserteq(2 + 251 * 2 + 1, info.start);
>+      ut_asserteq_str("00000000-100", disk_partition_uuid(&info));
>+

Linux include/linux/blkdev.h has:

"MSDOS UUID is 11 characters."
So this change looks wrong.

Best regards

Heinrich


>+      return 0;
>+}
>+DM_TEST(dm_test_part_dos_uuid, UTF_SCAN_PDATA | UTF_SCAN_FDT);

Reply via email to