The capsule update code takes several lengths and offsets from a capsule and uses them without checking them against the size of the capsule. On the capsule on disk path this happens before the image is authenticated, so a capsule file in \EFI\UpdateCapsule on the ESP makes U-Boot read outside the capsule buffer the next time capsule on disk runs, even where CONFIG_EFI_CAPSULE_AUTHENTICATE rejects the capsule afterwards.
Patches 1-4 check the capsule file size, the capsule header size, the FMP capsule layout (header, item offset list, item offsets, image and vendor code sizes) and the certificate length of an image, each against the size of the capsule. Patch 5 checks the FMP payload header size; with CONFIG_EFI_CAPSULE_AUTHENTICATE that header is part of the signed image, so there it is hardening. Patch 6 adds unit tests for patches 2-4, and patch 7 capsule on disk tests for patches 1 and 5. Each test fails without the patch it covers, except the one for patch 1: a capsule file shorter than its header is usually rejected anyway, because the read past the end of its buffer picks up heap data. Valgrind (CONFIG_VALGRIND) reports that read without patch 1 and nothing with it. The FWU accept capsule check of patch 2 has no test, as no sandbox configuration enables FWU_MULTI_BANK_UPDATE. On an MbedTLS build a malformed certificate of valid length still crashes sandbox in efi_signature_verify(), with or without this series: pkcs7_parse_message() returns ERR_PTR() of an MbedTLS error code, which IS_ERR() does not catch. Vsevolod Kozlov's "lib/mbedtls: Do not use ERR_PTR with mbedTLS error values" fixes that. CI: Azure build 13698 passed, all 91 jobs, with this series on https://github.com/u-boot/u-boot/pull/1064, a CI-only pull request that also carries my USB Ethernet rx, ext4 v2 and block size v2 series, merged with main c267fa81d42: https://dev.azure.com/u-boot/u-boot/_build/results?buildId=13698 Changes in v2: - Use size_t for item and item_count in patch 3 (Heinrich) - Test a capsule header running past the end of the capsule in patch 6 - Add patch 7, capsule on disk tests for patches 1 and 5 (Heinrich) - Add Ilias's Reviewed-by to patch 1 - Rebase on main Ana Bobillo (7): efi_loader: capsule: check the size of a capsule file efi_loader: capsule: check the capsule header size efi_loader: capsule: check the FMP capsule against its size efi_loader: capsule: check the certificate length of an image efi_loader: firmware: check the FMP payload header size test: lib: add tests for the capsule size checks test: py: efi_capsule: test truncated capsules and FMP payload headers arch/sandbox/dts/sandbox_capsule.dtsi | 52 +++++ lib/efi_loader/efi_capsule.c | 64 ++++-- lib/efi_loader/efi_firmware.c | 20 +- test/lib/Makefile | 1 + test/lib/efi_capsule.c | 212 ++++++++++++++++++ .../test_capsule_firmware_raw.py | 34 +++ .../test_capsule_firmware_signed_raw.py | 56 +++++ 7 files changed, 420 insertions(+), 19 deletions(-) create mode 100644 test/lib/efi_capsule.c base-commit: 8649a54d301a4d0ac526324c7a7ad2574939ff27
