From nobody Sat Feb 7 07:12:13 2026 Received: from todd.t-8ch.de (todd.t-8ch.de [159.69.126.157]) (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 35EA63904CB; Tue, 13 Jan 2026 12:37:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.69.126.157 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768307871; cv=none; b=epV6CouOiNIzYPw/O2jSF5Zv7b01GpDlrj4sy/y1eP8akB2zVeHsEBvg33aHPR68ccmVbeAINA40flqKTG1Ne0d8bOhlNsbTq3rZVl6veUeH9gwG8SrQGWQoBI7ab5m9lxQtl6CcsHNG3NaSGtbxy5Ezx/KMscMw8g0UGQ1y4WI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1768307871; c=relaxed/simple; bh=CQhD/KGKFcEkKh29q46LO6yIz88u0jgba+z/o0psTK8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=mJ/BPxk2oYqsi/cfIM9VfUlnjAkdZn/2SVNqaVmFtuy3HteQcPR4XAslp3k0aeB1BV1No/hB1oS7n4eh8o6GNynF3FWIfWbnku7itBQ1zeT2oeOvznFpHa1rhairb+hBNshWz652xQchq4aThP58E+KKr7AiVl+h1UPBC+Cx890= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net; spf=pass smtp.mailfrom=weissschuh.net; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b=SQt5bsbc; arc=none smtp.client-ip=159.69.126.157 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=weissschuh.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=weissschuh.net header.i=@weissschuh.net header.b="SQt5bsbc" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1768307860; bh=CQhD/KGKFcEkKh29q46LO6yIz88u0jgba+z/o0psTK8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=SQt5bsbcTnZS6yVdJ+LbYNoNhZEev1knGv0MjS71iiJfYlcuZyQ0aclRnK2Kr2PEq pavJTbLtAToGXld4GXml/FzTK76fJkWiqqk/Kz8PX+XPWi3Lxu2deHodM7LlKElFYY diHZjbVi1BV4pnlweGQP0Xpvny06OHosoDM+JiQE= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Tue, 13 Jan 2026 13:28:52 +0100 Subject: [PATCH v4 08/17] module: Deduplicate signature extraction Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260113-module-hashes-v4-8-0b932db9b56b@weissschuh.net> References: <20260113-module-hashes-v4-0-0b932db9b56b@weissschuh.net> In-Reply-To: <20260113-module-hashes-v4-0-0b932db9b56b@weissschuh.net> To: Nathan Chancellor , Arnd Bergmann , Luis Chamberlain , Petr Pavlu , Sami Tolvanen , Daniel Gomez , Paul Moore , James Morris , "Serge E. Hallyn" , Jonathan Corbet , Madhavan Srinivasan , Michael Ellerman , Nicholas Piggin , Naveen N Rao , Mimi Zohar , Roberto Sassu , Dmitry Kasatkin , Eric Snowberg , Nicolas Schier , Daniel Gomez , Aaron Tomlin , "Christophe Leroy (CS GROUP)" , Nicolas Schier , Nicolas Bouchinet , Xiu Jianfeng , Nicolas Schier , Christophe Leroy Cc: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= , Arnout Engelen , Mattia Rizzolo , kpcyrd , Christian Heusel , =?utf-8?q?C=C3=A2ju_Mihai-Drosi?= , Sebastian Andrzej Siewior , linux-kbuild@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arch@vger.kernel.org, linux-modules@vger.kernel.org, linux-security-module@vger.kernel.org, linux-doc@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linux-integrity@vger.kernel.org, =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1768307859; l=6766; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=CQhD/KGKFcEkKh29q46LO6yIz88u0jgba+z/o0psTK8=; b=Lgwo+6a5vIb8KpZTzvY+IyZL0lz4STVveaUDYDrKMqidgIHufGS8BuIXNHMAXiv7IHzs4yXTq YDRiGJTfok3AifwJoS+EQEosFVHWUVaOei8HsTi+t5sMgtnUNgIVDKo X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= The logic to extract the signature bits from a module file are duplicated between the module core and IMA modsig appraisal. Unify the implementation. Signed-off-by: Thomas Wei=C3=9Fschuh --- include/linux/module_signature.h | 4 +-- kernel/module/signing.c | 52 +++++++--------------------------= ---- kernel/module_signature.c | 41 +++++++++++++++++++++++++++-- security/integrity/ima/ima_modsig.c | 24 ++++------------- 4 files changed, 56 insertions(+), 65 deletions(-) diff --git a/include/linux/module_signature.h b/include/linux/module_signat= ure.h index 7eb4b00381ac..186a55effa30 100644 --- a/include/linux/module_signature.h +++ b/include/linux/module_signature.h @@ -40,7 +40,7 @@ struct module_signature { __be32 sig_len; /* Length of signature data */ }; =20 -int mod_check_sig(const struct module_signature *ms, size_t file_len, - const char *name); +int mod_split_sig(const void *buf, size_t *buf_len, bool mangled, + size_t *sig_len, const u8 **sig, const char *name); =20 #endif /* _LINUX_MODULE_SIGNATURE_H */ diff --git a/kernel/module/signing.c b/kernel/module/signing.c index fe3f51ac6199..6d64c0d18d0a 100644 --- a/kernel/module/signing.c +++ b/kernel/module/signing.c @@ -37,54 +37,22 @@ void set_module_sig_enforced(void) sig_enforce =3D true; } =20 -/* - * Verify the signature on a module. - */ -static int mod_verify_sig(const void *mod, struct load_info *info) -{ - struct module_signature ms; - size_t sig_len, modlen =3D info->len; - int ret; - - pr_devel("=3D=3D>%s(,%zu)\n", __func__, modlen); - - if (modlen <=3D sizeof(ms)) - return -EBADMSG; - - memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms)); - - ret =3D mod_check_sig(&ms, modlen, "module"); - if (ret) - return ret; - - sig_len =3D be32_to_cpu(ms.sig_len); - modlen -=3D sig_len + sizeof(ms); - info->len =3D modlen; - - return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, - VERIFY_USE_SECONDARY_KEYRING, - VERIFYING_MODULE_SIGNATURE, - NULL, NULL); -} - int module_sig_check(struct load_info *info, int flags) { - int err =3D -ENODATA; - const unsigned long markerlen =3D sizeof(MODULE_SIG_STRING) - 1; + int err; const char *reason; const void *mod =3D info->hdr; + size_t sig_len; + const u8 *sig; bool mangled_module =3D flags & (MODULE_INIT_IGNORE_MODVERSIONS | MODULE_INIT_IGNORE_VERMAGIC); - /* - * Do not allow mangled modules as a module with version information - * removed is no longer the module that was signed. - */ - if (!mangled_module && - info->len > markerlen && - memcmp(mod + info->len - markerlen, MODULE_SIG_STRING, markerlen) =3D= =3D 0) { - /* We truncate the module to discard the signature */ - info->len -=3D markerlen; - err =3D mod_verify_sig(mod, info); + + err =3D mod_split_sig(info->hdr, &info->len, mangled_module, &sig_len, &s= ig, "module"); + if (!err) { + err =3D verify_pkcs7_signature(mod, info->len, sig, sig_len, + VERIFY_USE_SECONDARY_KEYRING, + VERIFYING_MODULE_SIGNATURE, + NULL, NULL); if (!err) { info->sig_ok =3D true; return 0; diff --git a/kernel/module_signature.c b/kernel/module_signature.c index 00132d12487c..b2384a73524c 100644 --- a/kernel/module_signature.c +++ b/kernel/module_signature.c @@ -8,6 +8,7 @@ =20 #include #include +#include #include #include =20 @@ -18,8 +19,8 @@ * @file_len: Size of the file to which @ms is appended. * @name: What is being checked. Used for error messages. */ -int mod_check_sig(const struct module_signature *ms, size_t file_len, - const char *name) +static int mod_check_sig(const struct module_signature *ms, size_t file_le= n, + const char *name) { if (be32_to_cpu(ms->sig_len) >=3D file_len - sizeof(*ms)) return -EBADMSG; @@ -44,3 +45,39 @@ int mod_check_sig(const struct module_signature *ms, siz= e_t file_len, =20 return 0; } + +int mod_split_sig(const void *buf, size_t *buf_len, bool mangled, + size_t *sig_len, const u8 **sig, const char *name) +{ + const unsigned long markerlen =3D sizeof(MODULE_SIG_STRING) - 1; + struct module_signature ms; + size_t modlen =3D *buf_len; + int ret; + + /* + * Do not allow mangled modules as a module with version information + * removed is no longer the module that was signed. + */ + if (!mangled && + *buf_len > markerlen && + memcmp(buf + modlen - markerlen, MODULE_SIG_STRING, markerlen) =3D=3D= 0) { + /* We truncate the module to discard the signature */ + modlen -=3D markerlen; + } + + if (modlen <=3D sizeof(ms)) + return -EBADMSG; + + memcpy(&ms, buf + (modlen - sizeof(ms)), sizeof(ms)); + + ret =3D mod_check_sig(&ms, modlen, name); + if (ret) + return ret; + + *sig_len =3D be32_to_cpu(ms.sig_len); + modlen -=3D *sig_len + sizeof(ms); + *buf_len =3D modlen; + *sig =3D buf + modlen; + + return 0; +} diff --git a/security/integrity/ima/ima_modsig.c b/security/integrity/ima/i= ma_modsig.c index 3265d744d5ce..a57342d39b07 100644 --- a/security/integrity/ima/ima_modsig.c +++ b/security/integrity/ima/ima_modsig.c @@ -40,44 +40,30 @@ struct modsig { int ima_read_modsig(enum ima_hooks func, const void *buf, loff_t buf_len, struct modsig **modsig) { - const size_t marker_len =3D strlen(MODULE_SIG_STRING); - const struct module_signature *sig; + size_t buf_len_sz =3D buf_len; struct modsig *hdr; size_t sig_len; - const void *p; + const u8 *sig; int rc; =20 - if (buf_len <=3D marker_len + sizeof(*sig)) - return -ENOENT; - - p =3D buf + buf_len - marker_len; - if (memcmp(p, MODULE_SIG_STRING, marker_len)) - return -ENOENT; - - buf_len -=3D marker_len; - sig =3D (const struct module_signature *)(p - sizeof(*sig)); - - rc =3D mod_check_sig(sig, buf_len, func_tokens[func]); + rc =3D mod_split_sig(buf, &buf_len_sz, true, &sig_len, &sig, func_tokens[= func]); if (rc) return rc; =20 - sig_len =3D be32_to_cpu(sig->sig_len); - buf_len -=3D sig_len + sizeof(*sig); - /* Allocate sig_len additional bytes to hold the raw PKCS#7 data. */ hdr =3D kzalloc(struct_size(hdr, raw_pkcs7, sig_len), GFP_KERNEL); if (!hdr) return -ENOMEM; =20 hdr->raw_pkcs7_len =3D sig_len; - hdr->pkcs7_msg =3D pkcs7_parse_message(buf + buf_len, sig_len); + hdr->pkcs7_msg =3D pkcs7_parse_message(sig, sig_len); if (IS_ERR(hdr->pkcs7_msg)) { rc =3D PTR_ERR(hdr->pkcs7_msg); kfree(hdr); return rc; } =20 - memcpy(hdr->raw_pkcs7, buf + buf_len, sig_len); + memcpy(hdr->raw_pkcs7, sig, sig_len); =20 /* We don't know the hash algorithm yet. */ hdr->hash_algo =3D HASH_ALGO__LAST; --=20 2.52.0