All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/14] block, disk: Check block sizes and partition tables of devices
@ 2026-11-01  7:01 Ana Bobillo
  2026-11-01  7:01 ` [PATCH v3 01/14] treewide: Use is_power_of_2() from linux/log2.h Ana Bobillo
                   ` (13 more replies)
  0 siblings, 14 replies; 20+ messages in thread
From: Ana Bobillo @ 2026-11-01  7:01 UTC (permalink / raw)
  To: Tom Rini
  Cc: u-boot, Simon Glass, Marek Vasut, Bin Meng, Neil Armstrong,
	Heinrich Schuchardt, Ilias Apalodimas, Alexey Charkov,
	Javier Martinez Canillas, Marek Behún, Qu Wenruo,
	Matthias Brugger, Peter Robinson, Peng Fan, Jaehoon Chung,
	Tanmay Kathpalia

U-Boot scans the partitions of a block device as soon as it probes it,
and takes several sizes from the device and from its partition tables
as they are. A USB stick or SD card that U-Boot merely probes can
therefore make it read or write outside its buffers. This series checks
those sizes where they are read.

Block size. A block driver sets the block size of a device from what
the device reports, and only the virtio block driver and the host
command check it. The partition and filesystem code sizes buffers by the
block size, expects a block to hold a 512-byte boot sector and converts
between bytes and blocks with log2(blksz). So a USB stick, SCSI disk,
ATAPI drive or NVMe namespace reporting a block size below 512 bytes,
one that is not a power of two or a huge one makes U-Boot read or write
outside its buffers, in the partition scan run when the device is probed
and in the filesystem code after it.

Patch 1 drops two local copies of is_power_of_2(), so that blk.h can
use the one in linux/log2.h, and patch 2 adds blk_valid_blksz() there.
Patch 3 fixes the reply the USB storage driver makes up when READ
CAPACITY fails, which gave a 128KiB block size on a little-endian host.
Patches 4-7 check the block size where the USB storage, SCSI, IDE
(ATAPI) and NVMe drivers read it, so that each refuses such a device
cleanly: the USB LUN is skipped instead of failing the whole stick, no
SCSI block device is created, the ATAPI drive is treated as one without
a medium and the NVMe namespace is skipped like an inactive one. Patch 8
then has blk_post_probe() refuse a block device whose block size
blk_valid_blksz() rejects, which covers every block driver when its
device is probed, outside SPL and TPL (their size limits leave no room
for it). The MMC code sets the block size of a card again when it
initialises the card anew, as "mmc rescan" does, which that check does
not see: patch 14 has it always use 512-byte blocks, whatever block
length the card reports, as it already did in DDR mode.

The upper bound is 64KiB, the largest logical block size Linux accepts;
the GPT code is already tested with block sizes up to 32KiB.

Partition tables. Patch 9 checks the header size and the size of the
partition entry array of a GPT, as Linux does, before they size the CRC
of the header and the entry buffer. It leaves alloc_read_gpt_entries()
alone, so it applies with or without Benoît Monin's "disk: efi: Reuse
the GPT entries buffer with simple malloc". Patch 10 walks the chain of
DOS extended partition tables in a loop: a table linking back to itself
adds no partition, so the limit added for CVE-2019-13103 did not stop
the recursion. As Linux does, the walk now gives up after a few tables
in a row that hold no partition. Patch 11 makes room for partition
number 256 in the UUID made up for a DOS partition. Patch 12 has the
TCG2 measurement of the GPT measure the GPT the partition driver uses,
read with the driver's own code. It read the primary GPT itself,
unchecked, while the driver falls back to the backup GPT when the
primary one is not valid, so PCR 5 could hold a GPT the partitions were
not found in, and the sizes in an unchecked header could make the
measurement read past its buffer. Patch 13 then indexes the entries
directly there, as they now always have the size of a gpt_entry.

Patches 4, 5, 8-12 and 14 add tests: DM tests on sandbox, for the GPT a
test in test/lib on a blkmap device, and for the TCG2 measurement a test
in test/py that starts an EFI application from a GPT disk on sandbox and
checks PCR 5. With the series they pass, as do the rest of "ut dm" and
"ut lib" on sandbox_defconfig with CONFIG_ASAN (but for lib_crypt, which
ASan flags without the series too), and each patch builds and passes the
tests present so far on its own. The test/py test is skipped with
CONFIG_ASAN, under which sandbox cannot run an EFI application; on
sandbox_defconfig it passes, as do the other EFI, TPM and GPT tests in
test/py. The IDE and NVMe changes are build tested only, as sandbox has
no emulator for them.

CI: the series passes all 91 jobs of U-Boot's Azure pipeline, in build
13719 of my CI-only pull request, on main 3401e006432.
PR:    https://github.com/u-boot/u-boot/pull/1064
Build: https://dev.azure.com/u-boot/u-boot/_build/results?buildId=13719

Changes in v3:
- Add Simon's Reviewed-by to patches 1-11
- Patch 12: rename part_get_gpt_primary() to part_get_gpt(), measure
  the backup header as it is when the primary header is marked IGNOREME
  (ChromeOS), name the device in the warning when no valid GPT is read,
  and shorten the commit message (Simon)
- New patch 13, which indexes the GPT entries directly in
  tcg2_measure_gpt_data() and reads their count with le32_to_cpu()
  (Simon)
- New patch 14, which has the MMC code always use 512-byte blocks, as
  blk_post_probe() does not see the block size it sets when a card is
  initialised again
- Rebase on current main, which needed no changes to the patches

Changes in v2:
- Reorder the block size patches, so that each step is bisectable: the
  helper first, then the driver patches, and the blk_post_probe() check
  last (Simon)
- Use is_power_of_2() in blk_valid_blksz() (Simon), after a new patch 1
  that drops the local copies in the btrfs code and bcm2835_sdhost, which
  clash with it
- Split the USB READ CAPACITY fallback fix into a patch of its own, with
  a Fixes: tag, and fake 2880 blocks rather than 2881 (Simon)
- Name the LUN that the USB storage driver skips, and check the message
  in the test (Simon)
- Take the ATAPI block sizes 0, 2340 and 2352 as 2048, as Linux does,
  and say what is skipped otherwise (Simon)
- Leave the blk_post_probe() check out of SPL and TPL, where it took the
  SPL of imx28_btt3 and popmetal-rk3288 over their size limits and broke
  the link of evb-rk3036's, and say why it is outside the PARTITIONS
  condition (Simon)
- Include linux/sizes.h in part_efi.c, and word the GPT commit message
  so that the fastboot path is not taken as fully covered (Simon)
- Write the DOS walk as a for loop with a helper that follows the links,
  and stop it after 16 tables in a row without a partition (Simon)
- Measure the GPT the partition driver uses, which checks the CRC of
  the entries too (Simon), and when the primary GPT is not valid the
  backup one, with the primary header made from it, as EDK2 does
  (Ilias); say what the bug does to PCR 5 (Ilias)
- Avoid ut_assertok() of a known -ENOMEM in the GPT test (Coverity)

Ana Bobillo (14):
  treewide: Use is_power_of_2() from linux/log2.h
  block: Add blk_valid_blksz() to check a block size
  usb: storage: Fix the capacity faked when READ CAPACITY fails
  usb: storage: Refuse a block size the block layer cannot use
  scsi: Refuse a block size the block layer cannot use
  ide: Refuse an ATAPI block size atapi_read() cannot read
  nvme: Skip a namespace with an unsupported LBA data size
  block: Refuse a device with an unsupported block size
  disk: part_efi: Check the header and entry sizes of a GPT
  disk: part_dos: Walk the extended partition tables in a bounded loop
  disk: part_dos: Make room for a three-digit partition number in the
    UUID
  efi_loader: Measure the GPT the partition driver uses
  efi_loader: Index the GPT entries directly in tcg2_measure_gpt_data()
  mmc: Always use a 512-byte block length

 arch/sandbox/include/asm/test.h  |  30 ++++
 cmd/host.c                       |   5 +-
 common/usb_storage.c             |  10 +-
 disk/part_dos.c                  | 291 ++++++++++++++++++-------------
 disk/part_efi.c                  |  74 +++++++-
 drivers/block/blk-uclass.c       |  15 ++
 drivers/block/ide.c              |  23 ++-
 drivers/mmc/bcm2835_sdhost.c     |   6 +-
 drivers/mmc/mmc.c                |  34 ++--
 drivers/mmc/sandbox_mmc.c        |  11 +-
 drivers/nvme/nvme.c              |  33 +++-
 drivers/scsi/sandbox_scsi.c      |   8 +
 drivers/scsi/scsi.c              |   4 +
 drivers/usb/emul/sandbox_flash.c |   8 +
 drivers/virtio/virtio_blk.c      |   2 +-
 fs/btrfs/compat.h                |   6 +-
 include/blk.h                    |  21 +++
 include/part.h                   |  27 +++
 lib/efi_loader/efi_tcg2.c        |  76 ++++----
 test/dm/blk.c                    |  41 +++++
 test/dm/mmc.c                    |  40 +++++
 test/dm/part.c                   | 221 +++++++++++++++++++++++
 test/dm/scsi.c                   |  37 ++++
 test/dm/usb.c                    |  51 ++++++
 test/lib/part_efi.c              | 222 +++++++++++++++++++++++
 test/py/tests/test_efi_tcg2.py   | 246 ++++++++++++++++++++++++++
 26 files changed, 1329 insertions(+), 213 deletions(-)
 create mode 100644 test/py/tests/test_efi_tcg2.py


base-commit: 3401e006432abcbf7d73d7210f10df157f990ed3

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2026-11-01 15:01 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-01  7:01 [PATCH v3 00/14] block, disk: Check block sizes and partition tables of devices Ana Bobillo
2026-11-01  7:01 ` [PATCH v3 01/14] treewide: Use is_power_of_2() from linux/log2.h Ana Bobillo
2026-11-01  7:01 ` [PATCH v3 02/14] block: Add blk_valid_blksz() to check a block size Ana Bobillo
2026-11-01  7:01 ` [PATCH v3 03/14] usb: storage: Fix the capacity faked when READ CAPACITY fails Ana Bobillo
2026-11-01  7:01 ` [PATCH v3 04/14] usb: storage: Refuse a block size the block layer cannot use Ana Bobillo
2026-11-01  7:02 ` [PATCH v3 05/14] scsi: " Ana Bobillo
2026-11-01  7:02 ` [PATCH v3 06/14] ide: Refuse an ATAPI block size atapi_read() cannot read Ana Bobillo
2026-11-01  7:02 ` [PATCH v3 07/14] nvme: Skip a namespace with an unsupported LBA data size Ana Bobillo
2026-11-01  7:02 ` [PATCH v3 08/14] block: Refuse a device with an unsupported block size Ana Bobillo
2026-11-01  7:02 ` [PATCH v3 09/14] disk: part_efi: Check the header and entry sizes of a GPT Ana Bobillo
2026-11-01  7:02 ` [PATCH v3 10/14] disk: part_dos: Walk the extended partition tables in a bounded loop Ana Bobillo
2026-11-01  7:02 ` [PATCH v3 11/14] disk: part_dos: Make room for a three-digit partition number in the UUID Ana Bobillo
2026-11-01  8:03   ` Heinrich Schuchardt
2026-11-01  8:43     ` Ana Bobillo
2026-11-01  7:02 ` [PATCH v3 12/14] efi_loader: Measure the GPT the partition driver uses Ana Bobillo
2026-11-01 14:59   ` Simon Glass
2026-11-01  7:03 ` [PATCH v3 13/14] efi_loader: Index the GPT entries directly in tcg2_measure_gpt_data() Ana Bobillo
2026-11-01 14:59   ` Simon Glass
2026-11-01  7:03 ` [PATCH v3 14/14] mmc: Always use a 512-byte block length Ana Bobillo
2026-11-01 15:01   ` Simon Glass

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.