[PATCH] crypto: asymmetric_keys - bound section data range in pefile_digest_pe_contents

Fabrice Derepas <[email protected]>
Newsgroups org.kernel.vger.linux-crypto,org.infradead.lists.kexec,org.kernel.vger.keyrings,org.kernel.vger.linux-kernel
Message-ID <[email protected]>
pefile_digest_pe_contents() hashes each PE section with

	crypto_shash_update(desc, pebuf + ctx->secs[i].data_addr,
			    ctx->secs[i].raw_data_size);

where both data_addr and raw_data_size come straight from the untrusted PE
section table. pefile_parse_binary() bounds only the section table's
location, never the sections' data ranges, and nothing else on the path
checks them. A section with data_addr and/or raw_data_size pointing outside
the image therefore reads past the pelen-byte buffer (CWE-125); a large
raw_data_size makes it read far past the end and fault.

Commit f7dd32c5179d ("crypto: asymmetric_keys - fix OOB read in
pefile_digest_pe_contents") recently fixed a sibling underflow in this same
function (the hashed_bytes + certs_size trailer computation); the
per-section read below was left unchecked.

This loop runs only after verify_pkcs7_signature() succeeds, so it requires
a validly signed image -- but not an attacker signing key. The PKCS#7
signature covers the SpcIndirectDataContent (a self-contained digest in the
certificate table), not the live section bytes, so tampering data_addr in a
publicly available signed image leaves the signature valid at that step
while the out-of-bounds read fires when this function recomputes the
digest. It is thus reachable by a local CAP_SYS_BOOT user via
kexec_file_load() with a tampered signed image; the access is an
out-of-bounds read only, but a large raw_data_size faults, which is a
denial of service when panic_on_oops is set.

Reject a section whose data range does not lie within the image before
hashing it.

Fixes: af316fc442ef ("pefile: Digest the PE binary and compare to the PKCS#7 data")
Assisted-by: copilot-cli:claude-opus-4-6 frama-c
Signed-off-by: Fabrice Derepas <[email protected]>
---
Note: f7dd32c5179d, which fixed the sibling underflow in this function, was
assigned CVE-2026-64544; this closes the per-section read it did not cover.

Reproduced under KASAN (CONFIG_KASAN_GENERIC, x86-64). Two things were shown:

  1. The defect + fix: a KUnit case calls pefile_digest_pe_contents() with a
     crafted context whose section has data_addr = pelen. Unpatched:
     slab-out-of-bounds read; patched: -ELIBBAD before the hash.

  2. The reachability, end-to-end against a real trusted keyring: a real EFI
     binary was signed with a test key embedded via CONFIG_SYSTEM_TRUSTED_KEYS,
     then its section data_addr was tampered (leaving the PKCS#7 byte-identical).
     Results from verify_pefile_signature(): the untampered image verifies (0),
     one signed by an untrusted key is rejected at verify_pkcs7_signature()
     (-ENOKEY), and the tampered-but-trusted image passes that step and takes
     the OOB read in pefile_digest_pe_contents(). So no signing key is required.

The KUnit case (item 1) is easy to package and I can submit it separately; the
end-to-end setup (item 2) needs an embedded trusted key and signed images, so
it is harder to ship standalone. Neither is included here.

 crypto/asymmetric_keys/verify_pefile.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c
index cec99db..4e84fcf 100644
--- a/crypto/asymmetric_keys/verify_pefile.c
+++ b/crypto/asymmetric_keys/verify_pefile.c
@@ -292,6 +292,11 @@ static int pefile_digest_pe_contents(const void *pebuf, unsigned int pelen,
 		i = canon[loop];
 		if (ctx->secs[i].raw_data_size == 0)
 			continue;
+		if (ctx->secs[i].data_addr > pelen ||
+		    ctx->secs[i].raw_data_size > pelen - ctx->secs[i].data_addr) {
+			kfree(canon);
+			return -ELIBBAD;
+		}
 		ret = crypto_shash_update(desc,
 					  pebuf + ctx->secs[i].data_addr,
 					  ctx->secs[i].raw_data_size);
base-commit: 3d6d817622b0a9721e3cc404df3469171582be13
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.