Re: [PATCH v2 1/2] crypto: asymmetric_keys - fix OOB read in pefile_parse_binary
From: Herbert Xu
Date: Fri Sep 04 2026 - 06:08:11 EST
On Sat, Aug 15, 2026 at 04:00:19PM +0200, Fabrice Derepas wrote:
> pefile_parse_binary() reads the size field of the certificate table's
> data-directory entry, which sits at fixed index 4 of the PE optional
> header's data directory:
>
> ctx->certs_size = ddir->certs.size;
>
> but nothing ensures index 4 is present. n_data_dirents (the untrusted
> NumberOfRvaAndSizes) is only upper-bounded against header_size and may be
> 0, and header_size need only satisfy cursor < header_size < datalen. A
> crafted PE with n_data_dirents = 0 and a tiny header_size therefore causes
> the ddir->certs.size read to land past the end of the image (CWE-125). The
> chkaddr() that bounds the certificate blob runs only after this read.
>
> verify_pefile_signature() is reached from kexec_file_load() (the
> lockdown/secure-boot enforced PE-image signature path), and the image is
> parsed before its signature is checked. The trigger needs CAP_SYS_BOOT and
> the access is out-of-bounds read only (no write).
>
> Require the certificate table's data-directory entry (index 4) to be
> present; the existing upper-bound check then keeps ddir->certs within
> [cursor, header_size).
>
> Fixes: 26d1164be37f ("pefile: Parse a PE binary to find a key and a signature contained therein")
> Assisted-by: copilot-cli:claude-opus-4-6 frama-c
> Signed-off-by: Fabrice Derepas <fabrice.derepas@xxxxxxxxxxxxx>
> ---
> v2: express the "index 4" bound as
> offsetof(struct data_directory, certs) / sizeof(*dde) rather than a
> literal 4, per Ignat Korchagin's review [1] -- self-documenting and it
> tracks the struct layout. It is the same value (offsetof is 32,
> sizeof(*dde) is 8, so the bound is 4). A KUnit test is added as 2/2.
>
> [1] https://lore.kernel.org/all/CAOs+rJVztmvHSkNxP_voc7E=girsstCKmqxG37pvO2kTaEk1TQ@xxxxxxxxxxxxxx/
>
> Reproduced under KASAN (CONFIG_KASAN_GENERIC, x86-64) with the KUnit case in
> 2/2: a crafted PE with data_dirs = 0 takes a slab-out-of-bounds read in
> pefile_parse_binary() on an unpatched kernel, and is rejected with -ELIBBAD
> (no KASAN report) with this patch.
>
> crypto/asymmetric_keys/verify_pefile.c | 5 +++++
> 1 file changed, 5 insertions(+)
All applied. Thanks.
--
Email: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt