From nobody Mon Sep 28 23:55:53 2026 Received: from smtp-relay-internal-0.canonical.com (smtp-relay-internal-0.canonical.com [185.125.188.122]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B1AF33CF04C for ; Fri, 14 Aug 2026 22:06:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.188.122 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786745221; cv=none; b=WDUb6xjL0LbV3p9k1VYNKguHuve5ntuoscZ/ueFvblssv+7VvgJM7RzGkYDCObFMPhPXZi9rT6BETMox2ntAkj564VWEoO/oeF/KnoqbO/wA6XyJA7QWul7N2cNBER7rIOt/rSrF3ymeQaVOWSJngTYKYUMo3v2swJkAoTLvoUg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786745221; c=relaxed/simple; bh=Vwkx0ZoHWUDiHBSds5LKxVpgpl6OLyNmZpu3e+NlSLw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=VMW7/PZPgmkTkztVXa+IBOq0qJsWRRU7lTbaO4QKez07QNonNuRHpj2N3QfTnU3shJMNdRnfYN3+3EUul03fyu8gchY6MUXnSHn2i/l6CGNHBcVfvLPrEjSLzKqfoYoEJz0Cp8HmBNLvOZ6vu4rKwwS8EAJ01Z6WqEpciKgD62M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=canonical.com; spf=pass smtp.mailfrom=canonical.com; dkim=pass (4096-bit key) header.d=canonical.com header.i=@canonical.com header.b=YBfUFt5O; arc=none smtp.client-ip=185.125.188.122 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=canonical.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=canonical.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (4096-bit key) header.d=canonical.com header.i=@canonical.com header.b="YBfUFt5O" Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 9C0F53FCAC for ; Fri, 14 Aug 2026 22:06:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical.com; s=20251003; t=1786745211; bh=kMizY76jEizmA24XR5LtanW2cG+cuGuImxHD37owg3s=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YBfUFt5Oci7sba3uogT1jS5DzB1iVmFiGlrRkzihI/UOZB3EfU92au9wz4aKlLn02 n1Ag5XE0odB/CevItd9t7IbJvUr3h0cI8G/skTgfjkTNoeakbjqdiUtSg1aM4/fTLc MHM+Kwaz2LcXMiua8MRg7T5J5m3I5Dcf7tJRMkBAruWKovVHN7rGQDQvq7K4c5ulki Arh/ODP+No4gG2gE46AwXITdhuT2o2Z7CtoWi/dPlUGerAPZa5F3f/MtFjoNTLm7QD 4rq7gRp6cBkrx6kD59C5TmZii0jXaYOgRNH0KiuBNsu2mhuczu6DBKxiIjK/xeXp8b fs9Cv2hh6uAOizcMtKx2epL2+x6QLn+l1rBdXeA1LlQ5DyB5WOiUFjTaOMlsr0cV2I M9hjZiSv1Kdt21E4vRDyWWgvqBdV9Lj6DNXZ23UdI3tWaMwo8cpUhfEDV72d3Fv9vf dAw5K3BEieWl7tDJvrzY39UIMgyTTHINYBtFQ6u4zz6w0cTF5YFgsw4B1BJCqVDETq +RL6blnXY4EDmFw2SylNFaNMO8VBicW2t9t2q4OAytDDVCPrqjOg0GF5f2gz6+7BTY gybsdvsONhH7jJmCinFWGsNOgObxIPgJqdUEam7omxBx3c1mENCfDxw4gzPaL4OLU2 tI4p7kd6iPSeZ8fFm4VzkaZo= Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-47faa02f707so972770f8f.1 for ; Fri, 14 Aug 2026 15:06:51 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786745211; x=1787350011; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=kMizY76jEizmA24XR5LtanW2cG+cuGuImxHD37owg3s=; b=bE0Tst23a5RWBm26ey+yFTRiRm/X2NXFYwkiqPJ1UdX4fEyzp1KzPjmhwtxFwNkAAK r5jghMXjwhmR5tin0gM5tCR2jCH2Q5YrZIsUJzJQM/HqS3xeU+VQoall16PYHO62Vlda B7euULbit5Ht1Nrs66lpx6Xjme1rDmrSUlBqtij1hBmq9GRZu9sXiqFoFXHv6qEhYKz/ QoTxTPSz6lSyGpbckEg1WH5qnyaT/CIdELtcO0t/XzE7Po7uJaC61diOKyKRymHFoLTg PUMILnTHavv0HEC/Sd+oWqaD8uyhSV1LLu/RaI64o84LbQ2fwMOzTLX+bWABY/LqSp8i JXKw== X-Forwarded-Encrypted: i=1; AHgh+Rrbwzd4aFxg+UncSrdxbFKAotknW6HP8deAofb5H6kapFqyKU9El24pOW48YehKWnwhNNqgbQaZeypdyRg=@vger.kernel.org X-Gm-Message-State: AOJu0Yycx/NBlxZgDAs2Ef2FTgTBnUv/1bYdlBjDpRX75Xss28GH6H8d LimgJC7sylsDaHdc4lfE4Wg4NbVy7XL7mJ8/6boMpdDijtd3NhzqqXglwaENVMKBBcCIa19uy0t OdXIKsS5NOYhHFt9pD3Z58yDxIon1+LJBDPHHjL/AIBiQHfmtX+OwemtgFZ/A3ffLaqyDFmP96y j1BCMbBQ== X-Gm-Gg: AR+sD12AfTYBL2mLPE77RpAjXYeOK1DIy06r8nnly/kVo9Lvg/o9vUSuEp+x8nxZHbJ oMdcuI3GtvocML5ZrQYME4pVm+cpFt8iamdUAHC3AP6XcY5js09tt/Nhak4n4hQ39gLfU4aYK/H oVgySsJaHYqoM5CNXeutYphZrFgWGr1tuROUh/bpqb1TKSLADYwjHRmxCVRfU0UyNtg84uHpw7g 2C/qtz4IxyZqqVXgvu9wjSL1Nq+L0MDcKgpCuyEx+N6xo/S8GsrifOuSPV/OhQnMwxRPBWzlVDk RZWH4ngpFW21fPKfe9FqbeqIDRayfw7CT5xQl8ewDkWM0qeJ9z0/G+0uRhjVOo9fEibvoQSL8Zy 3+z1w0CdNOoQgS6IKpk3mLiB9L5zpMHqZqxu00E7E+JSZBGAefQonjhtUsY+O8ZK2uPH3/Pajdn 1J+pNrCK7oaAION5mgqppQheUq X-Received: by 2002:adf:f288:0:b0:47f:f002:3656 with SMTP id ffacd0b85a97d-48160797e95mr11067521f8f.12.1786745210987; Fri, 14 Aug 2026 15:06:50 -0700 (PDT) X-Received: by 2002:adf:f288:0:b0:47f:f002:3656 with SMTP id ffacd0b85a97d-48160797e95mr11067469f8f.12.1786745210451; Fri, 14 Aug 2026 15:06:50 -0700 (PDT) Received: from t-14 (2a01cb0008832300cfadf2438a4761d3.ipv6.abo.wanadoo.fr. [2a01:cb00:883:2300:cfad:f243:8a47:61d3]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-4815f219e12sm10376551f8f.10.2026.08.14.15.06.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 14 Aug 2026 15:06:49 -0700 (PDT) From: Fabrice Derepas To: Ignat Korchagin , David Howells , Lukas Wunner , Herbert Xu Cc: Fabrice Derepas , "David S. Miller" , keyrings@vger.kernel.org, linux-crypto@vger.kernel.org, kexec@lists.infradead.org, linux-kernel@vger.kernel.org Subject: [PATCH v2] crypto: asymmetric_keys - bound PE section ranges in pefile_parse_binary Date: Sat, 15 Aug 2026 00:06:28 +0200 Message-ID: <20260814220631.1101496-1-fabrice.derepas@canonical.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" 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 the section table's location but not 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 was left unchecked. The digest 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 the digest is recomputed. 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. Validate each section's data range against the image when the section table is parsed, reusing the existing chkaddr() bounds macro. A malformed range is rejected with -ELIBBAD at parse time -- before signature verification and before any hashing -- so a bad image is never digested. 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 --- v2: - move the check into pefile_parse_binary() and reuse chkaddr(), per Ignat Korchagin's review [1], so a malformed image is rejected at parse time -- before signature verification and before hashing. v1 put the check in the pefile_digest_pe_contents() section loop. - because chkaddr() runs on every section, v2 also validates zero-size (raw_data_size =3D=3D 0) sections, which v1 and the shipping digest loop skip. This only rejects a zero-size section whose data_addr points past the image -- malformed input that real PEs never produce (.bss uses PointerToRawData =3D 0, which passes) -- and matches the "don't start on malformed data" intent. [1] https://lore.kernel.org/all/CAOs+rJXZ++7_o4L6LuT567FjdYsa=3D6NEki3qcFSR= X+ehJxpoVg@mail.gmail.com/ Tested under KASAN (CONFIG_KASAN_GENERIC, x86-64) with a KUnit case that calls verify_pefile_signature() on real images: a signed-then-tampered image (a section's data_addr set to pelen) is now rejected with -ELIBBAD in pefile_parse_binary(), before verify_pkcs7_signature() and with no KASAN splat, while an untampered signed image passes parse and reaches the signature check (-ENOKEY, as the test key is not trusted in this build). v1's KASAN repro -- a crafted context taken straight into the digest loop -- showed the slab-out-of-bounds this prevents. crypto/asymmetric_keys/verify_pefile.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_key= s/verify_pefile.c index cec99db14..c447597f7 100644 --- a/crypto/asymmetric_keys/verify_pefile.c +++ b/crypto/asymmetric_keys/verify_pefile.c @@ -30,6 +30,7 @@ static int pefile_parse_binary(const void *pebuf, unsigne= d int pelen, const struct data_dirent *dde; const struct section_header *sec; size_t cursor, datalen =3D pelen; + unsigned int loop; =20 kenter(""); =20 @@ -112,6 +113,14 @@ static int pefile_parse_binary(const void *pebuf, unsi= gned int pelen, return -ELIBBAD; ctx->secs =3D pebuf + cursor; =20 + /* pefile_digest_pe_contents() hashes each section's raw data using + * these fields directly; reject a section whose data range falls + * outside the image so hashing never reads past the buffer. + */ + for (loop =3D 0; loop < ctx->n_sections; loop++) + chkaddr(0, ctx->secs[loop].data_addr, + ctx->secs[loop].raw_data_size); + return 0; } =20 base-commit: d58772d8520c7ef247c4b95c9bd76d3a25da9ff5 --=20 2.53.0