From: Ana Bobillo <anabobillo3@gmail.com>
To: u-boot@lists.u-boot-project.org
Cc: Heinrich Schuchardt <xypron.glpk@gmx.de>,
Ilias Apalodimas <ilias.apalodimas@linaro.org>,
Tom Rini <trini@konsulko.com>
Subject: [PATCH 00/10] efi_loader: check PE images before using them
Date: Fri, 30 Oct 2026 06:13:34 +0000 [thread overview]
Message-ID: <633dddd6-ee22-4cd6-a8b6-cb7df0650fae@gmail.com> (raw)
U-Boot takes the offsets and sizes of a PE/COFF image from its headers
and uses them before it knows whether the image may run. With Secure
Boot on, efi_load_pe() authenticates the image first but goes on
copying and relocating it when authentication fails, and only then
returns EFI_SECURITY_VIOLATION; efi_image_parse(), which collects the
regions to hash, runs before the signature is checked, and so does the
walk of the certificate table. TCG2 measured boot parses every image as
well. So an image that will be refused, or one that is only measured,
can make U-Boot read or write outside its buffers, or hang.
This series checks those fields against the image where they are read,
along the lines of EDK2's PeCoffLoaderLib and DxeImageVerificationLib:
- patch 1 has efi_check_pe() check for a 64bit NT header again, as its
comment says;
- patch 2 checks the headers, the sections and the certificate table in
efi_image_parse(), and fails on errors of efi_image_region_add();
- patches 3-5 have efi_load_pe() reject, before allocating the image, a
section whose end wraps around, section data past the end of the file
and headers that do not fit into the image;
- patch 6 checks the relocation table against the image;
- patch 7 rejects a certificate table holding a certificate shorter than
its header, which made the walk loop forever, or longer than the rest
of the table;
- patch 8 refuses to load an image whose TCG2 measurement failed, as
EDK2 does, instead of starting it unmeasured;
- patches 9 and 10 add unit tests and a Secure Boot test.
barebox, whose EFI loader is based on this file, made several of the
same changes this year; patches 2, 3 and 4 follow them and say so.
Valid images are unaffected: the unit tests check PE32 and PE32+ images
with 16, 6 or 5 data directories and an unpadded last section, the EFI
selftests and the Secure Boot tests pass, and each patch builds on its
own. Tested on sandbox.
CI: Azure build 13710 passed, all jobs, with this series on
https://github.com/u-boot/u-boot/pull/1064, a CI-only pull request,
merged with main 03e45557e1f:
https://dev.azure.com/u-boot/u-boot/_build/results?buildId=13710
Ana Bobillo (10):
efi_loader: check the NT header size in efi_check_pe()
efi_loader: check the PE image ranges in efi_image_parse()
efi_loader: reject a PE section whose end wraps around
efi_loader: check PE section raw data against the image size
efi_loader: check that the PE headers fit into the loaded image
efi_loader: check the relocation table against the image size
efi_loader: check certificate lengths in efi_image_authenticate()
efi_loader: do not load an image that cannot be measured
test: lib: add tests for the PE image checks
test: py: test invalid certificate lengths in signed images
lib/efi_loader/efi_image_loader.c | 368 +++++++++++----
test/lib/Makefile | 2 +-
test/lib/efi_image_loader.c | 442 ++++++++++++++++++
test/py/tests/test_efi_secboot/conftest.py | 31 ++
test/py/tests/test_efi_secboot/test_signed.py | 36 ++
5 files changed, 781 insertions(+), 98 deletions(-)
create mode 100644 test/lib/efi_image_loader.c
base-commit: 03e45557e1f38a39a0c80fe30483130ff376cf92
next reply other threads:[~2026-10-30 6:13 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-30 6:13 Ana Bobillo [this message]
2026-10-30 6:13 ` [PATCH 01/10] efi_loader: check the NT header size in efi_check_pe() Ana Bobillo
2026-10-30 7:23 ` Ilias Apalodimas
2026-10-30 11:15 ` Heinrich Schuchardt
2026-10-30 11:40 ` Ana Bobillo
2026-10-30 6:13 ` [PATCH 02/10] efi_loader: check the PE image ranges in efi_image_parse() Ana Bobillo
2026-10-30 12:14 ` Heinrich Schuchardt
2026-10-30 12:49 ` Ana Bobillo
2026-10-30 6:13 ` [PATCH 03/10] efi_loader: reject a PE section whose end wraps around Ana Bobillo
2026-10-30 7:41 ` Ilias Apalodimas
2026-10-30 12:35 ` Heinrich Schuchardt
2026-10-30 12:49 ` Ana Bobillo
2026-10-30 6:14 ` [PATCH 04/10] efi_loader: check PE section raw data against the image size Ana Bobillo
2026-10-30 12:45 ` Heinrich Schuchardt
2026-10-30 12:51 ` Ana Bobillo
2026-10-30 6:14 ` [PATCH 05/10] efi_loader: check that the PE headers fit into the loaded image Ana Bobillo
2026-10-30 13:09 ` Heinrich Schuchardt
2026-10-30 14:05 ` Ana Bobillo
2026-10-30 6:14 ` [PATCH 06/10] efi_loader: check the relocation table against the image size Ana Bobillo
2026-10-30 6:14 ` [PATCH 07/10] efi_loader: check certificate lengths in efi_image_authenticate() Ana Bobillo
2026-10-30 6:14 ` [PATCH 08/10] efi_loader: do not load an image that cannot be measured Ana Bobillo
2026-10-30 7:22 ` Ilias Apalodimas
2026-10-30 7:54 ` Ana Bobillo
2026-10-30 9:23 ` Ilias Apalodimas
2026-10-30 10:04 ` Ana Bobillo
2026-10-30 6:14 ` [PATCH 09/10] test: lib: add tests for the PE image checks Ana Bobillo
2026-10-30 6:14 ` [PATCH 10/10] test: py: test invalid certificate lengths in signed images Ana Bobillo
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=633dddd6-ee22-4cd6-a8b6-cb7df0650fae@gmail.com \
--to=anabobillo3@gmail.com \
--cc=ilias.apalodimas@linaro.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