From: Ana Bobillo <anabobillo3@gmail.com>
To: Tom Rini <trini@konsulko.com>
Cc: u-boot@lists.u-boot-project.org, Simon Glass <sjg@chromium.org>,
Marek Vasut <marek.vasut+usb@mailbox.org>,
Bin Meng <bmeng.cn@gmail.com>,
Neil Armstrong <neil.armstrong@linaro.org>,
Heinrich Schuchardt <xypron.glpk@gmx.de>,
Ilias Apalodimas <ilias.apalodimas@linaro.org>,
Alexey Charkov <alchark@flipper.net>,
Javier Martinez Canillas <javierm@redhat.com>
Subject: [PATCH v4 10/14] disk: part_dos: Walk the extended partition tables in a bounded loop
Date: Wed, 04 Nov 2026 12:51:26 +0000 [thread overview]
Message-ID: <196d159e-9bf1-491f-9668-ae3f38f6b446@gmail.com> (raw)
In-Reply-To: <1369653d-e0d4-4baf-adef-895a24190250@gmail.com>
From: Ana Bobillo <anabobillo3@gmail.com>
part_get_info_extended() and print_partition_extended() follow the
links from one extended partition table to the next by recursing, and
stop at MAX_EXT_PARTS partitions, the limit added for CVE-2019-13103.
But a link adds no partition: an extended partition table holding only
a link back to itself does not advance part_num, so the recursion goes
on until the stack runs out, whenever a logical partition of the device
is looked up. Even within the limit, every level keeps a buffer of one
block on the stack, so a long chain of tables on a device with large
blocks needs megabytes of stack.
Follow the links in a loop instead, reusing the one buffer, with the
code that finds the next link in a helper, dos_next_table(), which both
functions use. As Linux does in parse_extended(), stop after
MAX_EXT_EMPTY (16) tables in a row that hold no partition: tables
linking back to each other are then given up after a few reads. Also
stop after MAX_EXT_TABLES tables in all, as many as MAX_EXT_PARTS
partitions need when each table holds one, so that no walk reads more
than that. A chain that also holds tables without a partition then
reads fewer than MAX_EXT_PARTS partitions; partitioning tools write one
logical partition per table.
print_partition_extended() follows every link of a table, where
part_get_info_extended() follows only the first, so it can list
partitions that cannot be looked up, under numbers that clash, and its
walk is not a chain but a tree. Follow only the first link there too.
Add tests with a table holding only a link between two logical
partitions and then a table that links only to itself, and with 15 and
16 such tables in a row before a logical partition.
Signed-off-by: Ana Bobillo <anabobillo3@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
---
(no changes since v2)
Changes in v2:
- Use a for loop rather than a backward goto, and move the code that
follows a link into a helper used by both functions (Simon)
- Also stop after 16 tables in a row without a partition, as Linux does,
so that the table in the test costs about 20 reads per lookup at probe
rather than 256 (Simon)
- Tidy the style of the lines the loop re-indents
- Use the present tense in the commit message (Simon)
- Call part_init() in the test rather than setting part_type (Simon)
- Add a table holding only a link to the test, and a test of the limit
of 16 tables in a row without a partition
disk/part_dos.c | 289 +++++++++++++++++++++++++++---------------------
test/dm/part.c | 175 +++++++++++++++++++++++++++++
2 files changed, 340 insertions(+), 124 deletions(-)
diff --git a/disk/part_dos.c b/disk/part_dos.c
index 4b560fde1fb..bc40d9d2829 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -28,6 +28,18 @@
* to use large numbers of partitions */
#define MAX_EXT_PARTS 256
+/*
+ * A link to the next extended partition table adds no partition, so tables
+ * linking back to each other do not advance part_num. As Linux does in
+ * parse_extended(), stop after MAX_EXT_EMPTY tables in a row that hold no
+ * partition, so that such a loop ends after a few reads. Also stop after
+ * MAX_EXT_TABLES tables in all, as many as MAX_EXT_PARTS partitions need,
+ * so that tables with and without partitions in turn cannot make a walk
+ * read more.
+ */
+#define MAX_EXT_EMPTY 16
+#define MAX_EXT_TABLES MAX_EXT_PARTS
+
static inline int is_extended(int part_type)
{
return (part_type == DOS_PART_TYPE_EXTENDED ||
@@ -126,6 +138,42 @@ static int part_test_dos(struct blk_desc *desc)
return 0;
}
+/**
+ * dos_next_table() - Follow the link from a partition table to the next one
+ *
+ * Only the first link of a table is followed: fdisk numbers the logical
+ * partitions along that chain.
+ *
+ * @buffer: Partition table just read
+ * @ext_part_sector: Sector of that table (0 for the MBR), updated to the
+ * sector of the next table
+ * @relative: Start of the extended partition, which the links of
+ * its tables are relative to, set from the link in the
+ * MBR
+ * Return: true if the table links to a next one, false if not
+ */
+static bool dos_next_table(unsigned char *buffer, lbaint_t *ext_part_sector,
+ lbaint_t *relative)
+{
+ dos_partition_t *pt;
+ int i;
+
+ pt = (dos_partition_t *)(buffer + DOS_PART_TBL_OFFSET);
+ for (i = 0; i < 4; i++, pt++) {
+ if (is_extended(pt->sys_ind)) {
+ lbaint_t lba_start = get_unaligned_le32(&pt->start_sect) +
+ *relative;
+
+ if (!*ext_part_sector)
+ *relative = lba_start;
+ *ext_part_sector = lba_start;
+ return true;
+ }
+ }
+
+ return false;
+}
+
/* Print a partition that is relative to its Extended partition table
*/
static void print_partition_extended(struct blk_desc *desc,
@@ -135,65 +183,61 @@ static void print_partition_extended(struct blk_desc *desc,
{
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, desc->blksz);
dos_partition_t *pt;
+ int tables, empty = 0;
int i;
- /* set a maximum recursion level */
- if (part_num > MAX_EXT_PARTS)
- {
- printf("** Nested DOS partitions detected, stopping **\n");
- return;
- }
-
- if (blk_dread(desc, ext_part_sector, 1, (ulong *)buffer) != 1) {
- printf ("** Can't read partition table on %d:" LBAFU " **\n",
- desc->devnum, ext_part_sector);
- return;
- }
- i=test_block_type(buffer);
- if (i != DOS_MBR) {
- printf ("bad MBR sector signature 0x%02x%02x\n",
- buffer[DOS_PART_MAGIC_OFFSET],
- buffer[DOS_PART_MAGIC_OFFSET + 1]);
- return;
- }
-
- if (!ext_part_sector)
- disksig = get_unaligned_le32(&buffer[DOS_PART_DISKSIG_OFFSET]);
+ for (tables = 0; ; tables++) {
+ int prev_num = part_num;
- /* Print all primary/logical partitions */
- pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
- for (i = 0; i < 4; i++, pt++) {
- /*
- * fdisk does not show the extended partitions that
- * are not in the MBR
- */
-
- if ((pt->sys_ind != 0) &&
- (ext_part_sector == 0 || !is_extended (pt->sys_ind)) ) {
- print_one_part(pt, ext_part_sector, part_num, disksig);
+ /* bound the walk */
+ if (part_num > MAX_EXT_PARTS || tables >= MAX_EXT_TABLES ||
+ empty >= MAX_EXT_EMPTY) {
+ printf("** Nested DOS partitions detected, stopping **\n");
+ return;
}
- /* Reverse engr the fdisk part# assignment rule! */
- if ((ext_part_sector == 0) ||
- (pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) {
- part_num++;
+ if (blk_dread(desc, ext_part_sector, 1, (ulong *)buffer) != 1) {
+ printf("** Can't read partition table on %d:" LBAFU " **\n",
+ desc->devnum, ext_part_sector);
+ return;
+ }
+ i = test_block_type(buffer);
+ if (i != DOS_MBR) {
+ printf("bad MBR sector signature 0x%02x%02x\n",
+ buffer[DOS_PART_MAGIC_OFFSET],
+ buffer[DOS_PART_MAGIC_OFFSET + 1]);
+ return;
}
- }
- /* Follows the extended partitions */
- pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
- for (i = 0; i < 4; i++, pt++) {
- if (is_extended (pt->sys_ind)) {
- lbaint_t lba_start
- = get_unaligned_le32 (&pt->start_sect) + relative;
+ if (!ext_part_sector)
+ disksig = get_unaligned_le32(&buffer[DOS_PART_DISKSIG_OFFSET]);
+
+ /* Print all primary/logical partitions */
+ pt = (dos_partition_t *)(buffer + DOS_PART_TBL_OFFSET);
+ for (i = 0; i < 4; i++, pt++) {
+ /*
+ * fdisk does not show the extended partitions that
+ * are not in the MBR
+ */
+
+ if ((pt->sys_ind != 0) &&
+ (ext_part_sector == 0 || !is_extended(pt->sys_ind))) {
+ print_one_part(pt, ext_part_sector, part_num,
+ disksig);
+ }
- print_partition_extended(desc, lba_start,
- !ext_part_sector ? lba_start :
- relative, part_num, disksig);
+ /* Reverse engr the fdisk part# assignment rule! */
+ if ((ext_part_sector == 0) ||
+ (pt->sys_ind != 0 && !is_extended(pt->sys_ind))) {
+ part_num++;
+ }
}
- }
+ empty = part_num > prev_num ? 0 : empty + 1;
- return;
+ /* Follows the extended partitions */
+ if (!dos_next_table(buffer, &ext_part_sector, &relative))
+ break;
+ }
}
/**
@@ -220,93 +264,90 @@ static int part_get_info_extended(struct blk_desc *desc,
ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, desc->blksz);
struct disk_partition wdinfo = { 0 };
dos_partition_t *pt;
+ int tables, empty = 0;
int i, ret;
int dos_type;
- /* set a maximum recursion level */
- if (part_num > MAX_EXT_PARTS)
- {
- printf("** Nested DOS partitions detected, stopping **\n");
- return -1;
- }
+ for (tables = 0; ; tables++) {
+ int prev_num = part_num;
- if (blk_dread(desc, ext_part_sector, 1, (ulong *)buffer) != 1) {
- printf ("** Can't read partition table on %d:" LBAFU " **\n",
- desc->devnum, ext_part_sector);
- return -1;
- }
- if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
- buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
- printf ("bad MBR sector signature 0x%02x%02x\n",
- buffer[DOS_PART_MAGIC_OFFSET],
- buffer[DOS_PART_MAGIC_OFFSET + 1]);
- return -1;
- }
+ /* bound the walk */
+ if (part_num > MAX_EXT_PARTS || tables >= MAX_EXT_TABLES ||
+ empty >= MAX_EXT_EMPTY) {
+ printf("** Nested DOS partitions detected, stopping **\n");
+ return -1;
+ }
- if (CONFIG_IS_ENABLED(PARTITION_UUIDS) && !ext_part_sector)
- disksig = get_unaligned_le32(&buffer[DOS_PART_DISKSIG_OFFSET]);
+ if (blk_dread(desc, ext_part_sector, 1, (ulong *)buffer) != 1) {
+ printf("** Can't read partition table on %d:" LBAFU " **\n",
+ desc->devnum, ext_part_sector);
+ return -1;
+ }
+ if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 ||
+ buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) {
+ printf("bad MBR sector signature 0x%02x%02x\n",
+ buffer[DOS_PART_MAGIC_OFFSET],
+ buffer[DOS_PART_MAGIC_OFFSET + 1]);
+ return -1;
+ }
- if (info) {
- ret = part_get_info_whole_disk(desc, &wdinfo);
- if (ret)
- return ret;
- }
+ if (CONFIG_IS_ENABLED(PARTITION_UUIDS) && !ext_part_sector)
+ disksig = get_unaligned_le32(&buffer[DOS_PART_DISKSIG_OFFSET]);
- /* Print all primary/logical partitions */
- pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
- for (i = 0; i < 4; i++, pt++) {
- /*
- * fdisk does not show the extended partitions that
- * are not in the MBR
- */
- if (((pt->boot_ind & ~0x80) == 0) &&
- (pt->sys_ind != 0) &&
- (part_num == which_part) &&
- (ext_part_sector == 0 || is_extended(pt->sys_ind) == 0)) {
- if (info) {
- if (wdinfo.blksz > DOS_PART_DEFAULT_SECTOR)
- info->blksz = wdinfo.blksz;
- else
- info->blksz = DOS_PART_DEFAULT_SECTOR;
- info->start = (lbaint_t)(ext_part_sector +
- get_unaligned_le32(&pt->start_sect));
- info->size = (lbaint_t)get_unaligned_le32(&pt->nr_sects);
- part_set_generic_name(desc, part_num,
- (char *)info->name);
- snprintf(info->type, sizeof(info->type), "0x%x", pt->sys_ind);
- info->bootable = get_bootable(pt);
- if (CONFIG_IS_ENABLED(PARTITION_UUIDS)) {
- char str[12];
-
- sprintf(str, "%08x-%02x", disksig, part_num);
- disk_partition_set_uuid(info, str);
+ if (info) {
+ ret = part_get_info_whole_disk(desc, &wdinfo);
+ if (ret)
+ return ret;
+ }
+
+ /* Print all primary/logical partitions */
+ pt = (dos_partition_t *)(buffer + DOS_PART_TBL_OFFSET);
+ for (i = 0; i < 4; i++, pt++) {
+ /*
+ * fdisk does not show the extended partitions that
+ * are not in the MBR
+ */
+ if (((pt->boot_ind & ~0x80) == 0) &&
+ (pt->sys_ind != 0) &&
+ (part_num == which_part) &&
+ (ext_part_sector == 0 || is_extended(pt->sys_ind) == 0)) {
+ if (info) {
+ if (wdinfo.blksz > DOS_PART_DEFAULT_SECTOR)
+ info->blksz = wdinfo.blksz;
+ else
+ info->blksz = DOS_PART_DEFAULT_SECTOR;
+ info->start = ext_part_sector +
+ get_unaligned_le32(&pt->start_sect);
+ info->size = get_unaligned_le32(&pt->nr_sects);
+ part_set_generic_name(desc, part_num,
+ (char *)info->name);
+ snprintf(info->type, sizeof(info->type),
+ "0x%x", pt->sys_ind);
+ info->bootable = get_bootable(pt);
+ if (CONFIG_IS_ENABLED(PARTITION_UUIDS)) {
+ char str[12];
+
+ sprintf(str, "%08x-%02x", disksig, part_num);
+ disk_partition_set_uuid(info, str);
+ }
+ info->sys_ind = pt->sys_ind;
}
- info->sys_ind = pt->sys_ind;
+ if (mbr)
+ memcpy(mbr, pt, sizeof(*mbr));
+ return 0;
}
- if (mbr)
- memcpy(mbr, pt, sizeof(*mbr));
- return 0;
- }
- /* Reverse engr the fdisk part# assignment rule! */
- if ((ext_part_sector == 0) ||
- (pt->sys_ind != 0 && !is_extended (pt->sys_ind)) ) {
- part_num++;
+ /* Reverse engr the fdisk part# assignment rule! */
+ if ((ext_part_sector == 0) ||
+ (pt->sys_ind != 0 && !is_extended(pt->sys_ind))) {
+ part_num++;
+ }
}
- }
+ empty = part_num > prev_num ? 0 : empty + 1;
- /* Follows the extended partitions */
- pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
- for (i = 0; i < 4; i++, pt++) {
- if (is_extended (pt->sys_ind)) {
- lbaint_t lba_start
- = get_unaligned_le32 (&pt->start_sect) + relative;
-
- return part_get_info_extended(desc, lba_start,
- ext_part_sector == 0 ? lba_start : relative,
- part_num, which_part, info,
- mbr, disksig);
- }
+ /* Follows the extended partitions */
+ if (!dos_next_table(buffer, &ext_part_sector, &relative))
+ break;
}
/* Check for DOS PBR if no partition is found */
diff --git a/test/dm/part.c b/test/dm/part.c
index ad37d7f406f..4938d962144 100644
--- a/test/dm/part.c
+++ b/test/dm/part.c
@@ -3,10 +3,13 @@
* Copyright (C) 2020 Sean Anderson <sean.anderson@seco.com>
*/
+#include <blk.h>
#include <dm.h>
#include <env.h>
+#include <memalign.h>
#include <mmc.h>
#include <part.h>
+#include <part_dos.h>
#include <part_efi.h>
#include <dm/test.h>
#include <test/ut.h>
@@ -248,3 +251,175 @@ static int dm_test_part_get_info_by_uuid(struct unit_test_state *uts)
return 0;
}
DM_TEST(dm_test_part_get_info_by_uuid, UTF_SCAN_PDATA | UTF_SCAN_FDT);
+
+/**
+ * dos_set_entry() - fill in one entry of a DOS partition table
+ *
+ * @pt: entry to fill in
+ * @sys_ind: partition type
+ * @start: first sector, relative to what the table type says
+ * @size: number of sectors
+ */
+static void dos_set_entry(dos_partition_t *pt, u8 sys_ind, u32 start,
+ u32 size)
+{
+ memset(pt, '\0', sizeof(*pt));
+ pt->sys_ind = sys_ind;
+ pt->start_sect = cpu_to_le32(start);
+ pt->nr_sects = cpu_to_le32(size);
+}
+
+/**
+ * dos_write_table() - write a DOS partition table to a sector
+ *
+ * @desc: block device to write to, with 512-byte blocks
+ * @lba: sector to write the table to
+ * @pt: the four entries of the table
+ * Return: 0 if OK, -EIO if the sector could not be written
+ */
+static int dos_write_table(struct blk_desc *desc, lbaint_t lba,
+ const dos_partition_t pt[4])
+{
+ ALLOC_CACHE_ALIGN_BUFFER(u8, buf, 512);
+
+ memset(buf, '\0', 512);
+ memcpy(buf + DOS_PART_TBL_OFFSET, pt, 4 * sizeof(*pt));
+ buf[DOS_PART_MAGIC_OFFSET] = 0x55;
+ buf[DOS_PART_MAGIC_OFFSET + 1] = 0xaa;
+
+ return blk_dwrite(desc, lba, 1, buf) == 1 ? 0 : -EIO;
+}
+
+/*
+ * A link from one extended partition table to the next adds no partition,
+ * so a walk through tables that link to each other in a loop finds no more
+ * partitions as it goes. Check that it ends anyway, both when looking for a
+ * partition and when listing them, and that a table holding only a link is
+ * still followed.
+ */
+static int dm_test_part_dos_ext_loop(struct unit_test_state *uts)
+{
+ struct disk_partition info;
+ dos_partition_t pt[4];
+ struct blk_desc *desc;
+
+ ut_asserteq(2, blk_get_device_by_str("mmc", "2", &desc));
+ ut_asserteq(512, desc->blksz);
+
+ /* an MBR with one extended partition, from sector 2 */
+ memset(pt, '\0', sizeof(pt));
+ dos_set_entry(&pt[0], DOS_PART_TYPE_EXTENDED, 2, 100);
+ ut_assertok(dos_write_table(desc, 0, pt));
+
+ /*
+ * logical partition 5 in a table of its own, then a table holding only
+ * a link, then logical partition 6; a link is relative to the extended
+ * partition, a partition to its own table
+ */
+ dos_set_entry(&pt[0], 0x83, 1, 4);
+ dos_set_entry(&pt[1], DOS_PART_TYPE_EXTENDED, 10, 10);
+ ut_assertok(dos_write_table(desc, 2, pt));
+ memset(pt, '\0', sizeof(pt));
+ dos_set_entry(&pt[0], DOS_PART_TYPE_EXTENDED, 20, 10);
+ ut_assertok(dos_write_table(desc, 12, pt));
+ dos_set_entry(&pt[0], 0x83, 1, 4);
+ dos_set_entry(&pt[1], DOS_PART_TYPE_EXTENDED, 30, 10);
+ ut_assertok(dos_write_table(desc, 22, pt));
+
+ /* then a table with no partition, only a link back to itself */
+ memset(pt, '\0', sizeof(pt));
+ dos_set_entry(&pt[0], DOS_PART_TYPE_EXTENDED, 30, 10);
+ ut_assertok(dos_write_table(desc, 32, pt));
+
+ ut_assertok(part_get_info_by_type(desc, 5, PART_TYPE_DOS, &info));
+ ut_asserteq(3, info.start);
+ ut_asserteq(4, info.size);
+ ut_assertok(part_get_info_by_type(desc, 6, PART_TYPE_DOS, &info));
+ ut_asserteq(23, info.start);
+ ut_asserteq(4, info.size);
+
+ /* there is no partition 7, and looking for it has to end */
+ ut_asserteq(-ENOENT,
+ part_get_info_by_type(desc, 7, PART_TYPE_DOS, &info));
+ ut_assert_nextline("** Nested DOS partitions detected, stopping **");
+ ut_assert_console_end();
+
+ /* and so does listing them, once the table is detected as DOS */
+ part_init(desc);
+ ut_asserteq(PART_TYPE_DOS, desc->part_type);
+ part_print(desc);
+ ut_assert_skip_to_line("%3d\t%-10d\t%-10d\t%08x-%02x\t%02x", 6, 23, 4,
+ 0, 6, 0x83);
+ ut_assert_nextline("** Nested DOS partitions detected, stopping **");
+ ut_assert_console_end();
+
+ return 0;
+}
+DM_TEST(dm_test_part_dos_ext_loop, UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_CONSOLE);
+
+/**
+ * dos_write_chain() - write a chain of extended partition tables
+ *
+ * The MBR holds an extended partition from sector 2, whose first table
+ * holds logical partition 5 and a link, then come @empty tables holding only
+ * a link, and then a table holding logical partition 6.
+ *
+ * @desc: block device to write to, with 512-byte blocks
+ * @empty: number of tables holding only a link
+ * Return: sector where partition 6 starts, or -EIO on error
+ */
+static int dos_write_chain(struct blk_desc *desc, int empty)
+{
+ dos_partition_t pt[4];
+ int i;
+
+ memset(pt, '\0', sizeof(pt));
+ dos_set_entry(&pt[0], DOS_PART_TYPE_EXTENDED, 2, 1000);
+ if (dos_write_table(desc, 0, pt))
+ return -EIO;
+
+ /* table n is at sector 2 + 10 * n, its link 10 * (n + 1) */
+ for (i = 0; i <= empty + 1; i++) {
+ memset(pt, '\0', sizeof(pt));
+ if (i == 0 || i == empty + 1)
+ dos_set_entry(&pt[0], 0x83, 1, 4);
+ if (i <= empty)
+ dos_set_entry(&pt[1], DOS_PART_TYPE_EXTENDED,
+ 10 * (i + 1), 10);
+ if (dos_write_table(desc, 2 + 10 * i, pt))
+ return -EIO;
+ }
+
+ return 2 + 10 * (empty + 1) + 1;
+}
+
+/*
+ * Check that a walk through the extended partition tables follows up to 15
+ * tables in a row holding no partition, as a damaged but valid chain may
+ * have, but gives up at the 16th
+ */
+static int dm_test_part_dos_ext_empty(struct unit_test_state *uts)
+{
+ struct disk_partition info;
+ struct blk_desc *desc;
+ int start;
+
+ ut_asserteq(2, blk_get_device_by_str("mmc", "2", &desc));
+ ut_asserteq(512, desc->blksz);
+
+ start = dos_write_chain(desc, 15);
+ ut_assert(start > 0);
+ ut_assertok(part_get_info_by_type(desc, 6, PART_TYPE_DOS, &info));
+ ut_asserteq(start, info.start);
+ ut_assert_console_end();
+
+ ut_assert(dos_write_chain(desc, 16) > 0);
+ ut_assertok(part_get_info_by_type(desc, 5, PART_TYPE_DOS, &info));
+ ut_asserteq(-ENOENT,
+ part_get_info_by_type(desc, 6, PART_TYPE_DOS, &info));
+ ut_assert_nextline("** Nested DOS partitions detected, stopping **");
+ ut_assert_console_end();
+
+ return 0;
+}
+DM_TEST(dm_test_part_dos_ext_empty, UTF_SCAN_PDATA | UTF_SCAN_FDT | UTF_CONSOLE);
next prev parent reply other threads:[~2026-11-04 12:51 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-04 12:50 [PATCH v4 00/14] block, disk: Check block sizes and partition tables of devices Ana Bobillo
2026-11-04 12:50 ` [PATCH v4 01/14] treewide: Use is_power_of_2() from linux/log2.h Ana Bobillo
2026-11-04 12:50 ` [PATCH v4 02/14] block: Add blk_valid_blksz() to check a block size Ana Bobillo
2026-11-04 12:50 ` [PATCH v4 03/14] usb: storage: Fix the capacity faked when READ CAPACITY fails Ana Bobillo
2026-11-04 12:50 ` [PATCH v4 04/14] usb: storage: Refuse a block size the block layer cannot use Ana Bobillo
2026-11-04 12:50 ` [PATCH v4 05/14] scsi: " Ana Bobillo
2026-11-04 12:51 ` [PATCH v4 06/14] ide: Refuse an ATAPI block size atapi_read() cannot read Ana Bobillo
2026-11-04 12:51 ` [PATCH v4 07/14] nvme: Skip a namespace with an unsupported LBA data size Ana Bobillo
2026-11-11 8:14 ` Neil Armstrong
2026-11-04 12:51 ` [PATCH v4 08/14] block: Refuse a device with an unsupported block size Ana Bobillo
2026-11-04 12:51 ` [PATCH v4 09/14] disk: part_efi: Check the header and entry sizes of a GPT Ana Bobillo
2026-11-04 12:51 ` Ana Bobillo [this message]
2026-11-04 12:51 ` [PATCH v4 11/14] disk: part_dos: Number at most 255 partitions, as Linux does Ana Bobillo
2026-11-04 12:51 ` [PATCH v4 12/14] efi_loader: Measure the GPT the partition driver uses Ana Bobillo
2026-11-04 12:51 ` [PATCH v4 13/14] efi_loader: Index the GPT entries directly in tcg2_measure_gpt_data() Ana Bobillo
2026-11-04 12:51 ` [PATCH v4 14/14] mmc: Always use a 512-byte block length Ana Bobillo
2026-11-09 9:33 ` Peng Fan
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=196d159e-9bf1-491f-9668-ae3f38f6b446@gmail.com \
--to=anabobillo3@gmail.com \
--cc=alchark@flipper.net \
--cc=bmeng.cn@gmail.com \
--cc=ilias.apalodimas@linaro.org \
--cc=javierm@redhat.com \
--cc=marek.vasut+usb@mailbox.org \
--cc=neil.armstrong@linaro.org \
--cc=sjg@chromium.org \
--cc=trini@konsulko.com \
--cc=u-boot@lists.u-boot-project.org \
--cc=xypron.glpk@gmx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).