From nobody Sun Feb 8 10:44:30 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 C428A1EBFE4; Mon, 20 Jan 2025 17:45:42 +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=1737395144; cv=none; b=MBZgNPrYDOWHC2Hz0WLWwlYifVBofCGrQG+msOMIdW4hdTeGkbXPOF2StmGtqj3jkoYxjpnPHoWG8YZw6nUXIHr2jLCM42pjwvZy6DrxcidhSYQsepkI2NmQM2y8WCXVhDGYsk8CKJ2khyLMmUOADbVQlBYjRCD+fu4olwskRKU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737395144; c=relaxed/simple; bh=HDDtbmikCEDSTHmKoHeEuCaqiT8pJK9CEVdCoy2Xjus=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Re1L9BSR1q5JMkVLuVCbRdbXPWockOoCJ4yMd9uvmlGh5Stf557xcii30JbPLG2jXM/Y17M671OaJjzfHReAeEur55RpeSWIRdxKfVZWJhYNPPfUf1YiaqA2Z3e/NORXH0+uAvBcGCsmnOCLj4jcAtskUyu2x7P8Q+5ISyhHTOg= 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=UeX/PmWz; 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="UeX/PmWz" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1737395132; bh=HDDtbmikCEDSTHmKoHeEuCaqiT8pJK9CEVdCoy2Xjus=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=UeX/PmWztk+p/6ZQS9PW34KmIjbSktI1uzZkkxJMG1XJMyKXdUnhgds3FB0do7gzO jD7WSHxDhw9r8u0pHL1eziFZqr2kiBXU48DMiXcS8gu0K8y5zru30Ap7DcFg30jGhf 6ovJYYzIEZHWvuT0cHFBLnoVUeKpIRzRtoPXJb7w= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Mon, 20 Jan 2025 18:44:20 +0100 Subject: [PATCH v2 1/6] kbuild: add stamp file for vmlinux BTF data 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: <20250120-module-hashes-v2-1-ba1184e27b7f@weissschuh.net> References: <20250120-module-hashes-v2-0-ba1184e27b7f@weissschuh.net> In-Reply-To: <20250120-module-hashes-v2-0-ba1184e27b7f@weissschuh.net> To: Masahiro Yamada , Nathan Chancellor , Nicolas Schier , Arnd Bergmann , Luis Chamberlain , Petr Pavlu , Sami Tolvanen , Daniel Gomez , Paul Moore , James Morris , "Serge E. Hallyn" , Jonathan Corbet Cc: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= , Arnout Engelen , Mattia Rizzolo , kpcyrd , 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, =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1737395132; l=2248; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=HDDtbmikCEDSTHmKoHeEuCaqiT8pJK9CEVdCoy2Xjus=; b=UYlaeR44AqJC7COzsLKEo6ELnaEGSvoeIBK0aU8S7+Y9eg7ng/SRYoAuLDiMtsQfEyTn2FD0g Ryo/YTiwBZEDrM2KhnQINuGzuatlDMCSKLEVfqboSmMjmD0/UWTMao2 X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= The upcoming module hashes functionality will build the modules in between the generation of the BTF data and the final link of vmlinux. Having a dependency from the modules on vmlinux would make this impossible as it would mean having a cyclic dependency. Break this cyclic dependency by introducing a new target. Signed-off-by: Thomas Wei=C3=9Fschuh --- scripts/Makefile.modfinal | 4 ++-- scripts/link-vmlinux.sh | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 542ba462ed3ec9607e0df10e26613a4c7ac318e8..5d01b553ec9a4565c8e5a6edd05= 665c409003bc1 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -52,8 +52,8 @@ if_changed_except =3D $(if $(call newer_prereqs_except,$(= 2))$(cmd-check), \ printf '%s\n' 'savedcmd_$@ :=3D $(make-cmd)' > $(dot-target).cmd, @:) =20 # Re-generate module BTFs if either module's .ko or vmlinux changed -%.ko: %.o %.mod.o .module-common.o $(objtree)/scripts/module.lds $(and $(C= ONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),$(objtree)/vmlinux) FORCE - +$(call if_changed_except,ld_ko_o,$(objtree)/vmlinux) +%.ko: %.o %.mod.o .module-common.o $(objtree)/scripts/module.lds $(and $(C= ONFIG_DEBUG_INFO_BTF_MODULES),$(KBUILD_BUILTIN),$(objtree)/.tmp_vmlinux_btf= .stamp) FORCE + +$(call if_changed_except,ld_ko_o,$(objtree)/.tmp_vmlinux_btf.stamp) ifdef CONFIG_DEBUG_INFO_BTF_MODULES +$(if $(newer-prereqs),$(call cmd,btf_ko)) endif diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index d853ddb3b28c1238ec9079ebbbe77df26980a0a1..803c8d6f35a7f29fb68b29afa85= 46f4dde0bd4cb 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -112,6 +112,7 @@ vmlinux_link() gen_btf() { local btf_data=3D${1}.btf.o + local btf_stamp=3D.tmp_vmlinux_btf.stamp =20 info BTF "${btf_data}" LLVM_OBJCOPY=3D"${OBJCOPY}" ${PAHOLE} -J ${PAHOLE_FLAGS} ${1} @@ -132,6 +133,11 @@ gen_btf() fi printf "${et_rel}" | dd of=3D"${btf_data}" conv=3Dnotrunc bs=3D1 seek=3D1= 6 status=3Dnone =20 + info STAMP $btf_stamp + if ! cmp --silent $btf_data $btf_stamp; then + cp $btf_data $btf_stamp + fi + btf_vmlinux_bin_o=3D${btf_data} } =20 --=20 2.48.1 From nobody Sun Feb 8 10:44:30 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 633B61F03C6; Mon, 20 Jan 2025 17:45:46 +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=1737395148; cv=none; b=QFq+RJ6O3rhy2G+NtWkNNV+CVY1eD5Q5IDhOpIKgipNGwLcNfXPoJGacUx5cmPf23MtuJ8hSWVdu8Ove/62bCfu92zTlJuDW8iK++FCQJy06oX3976dTS+VGpqQ43kszXG+hTxeysQUb7qke266MfqeCMQ800ApQ2VzK6AaTnAI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737395148; c=relaxed/simple; bh=y1mgrnaND/wbt141UjmnEkQzo6komHB3bc5SEQ4EwGw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=sIGV6zZex8YnHd6NwzHz6JH2iNTb0CNaVjcx6vFyQ73n+aYlklUqPzFo3ayclCz2A8zGoc6znsvuEzxLOTTZ9gauV898GB34GpOxulfD4gHyJOUIeum3NMo+HgjLogHYgNBlsxDuagR6Cfsecalh1tLzKW9zU4TVOsQZqPlyOwA= 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=seVdC/kI; 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="seVdC/kI" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1737395132; bh=y1mgrnaND/wbt141UjmnEkQzo6komHB3bc5SEQ4EwGw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=seVdC/kIx9ku41vBQZtDWVdtKljaDpjT3gCYCrswKvVuKyTicSY0q5/YXGIr7KOSB m6s0w4frFdRMqFCEyp/LcVUM+uGzpooiXw5t455H8ZgbVn3M+EgyIkO8GLY2wqG+2E BZgNqEMLkyZb+SS0hCDiXWvD37axweNkCVihw99I= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Mon, 20 Jan 2025 18:44:21 +0100 Subject: [PATCH v2 2/6] module: Make module loading policy usable without MODULE_SIG 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: <20250120-module-hashes-v2-2-ba1184e27b7f@weissschuh.net> References: <20250120-module-hashes-v2-0-ba1184e27b7f@weissschuh.net> In-Reply-To: <20250120-module-hashes-v2-0-ba1184e27b7f@weissschuh.net> To: Masahiro Yamada , Nathan Chancellor , Nicolas Schier , Arnd Bergmann , Luis Chamberlain , Petr Pavlu , Sami Tolvanen , Daniel Gomez , Paul Moore , James Morris , "Serge E. Hallyn" , Jonathan Corbet Cc: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= , Arnout Engelen , Mattia Rizzolo , kpcyrd , 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, =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1737395132; l=4529; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=y1mgrnaND/wbt141UjmnEkQzo6komHB3bc5SEQ4EwGw=; b=tyLGwa+HuW9EtJKxaGkD7GTxuCByB+DID2E1ITVJR5exbfWrL77NQhVr5hiuEAzwHu5QyjfM5 T9xfsr5I16fAcrqFS6jlRXVIgfj6dArJ36LVlQHPPKqyU9h92+sapTQ X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= The loading policy functionality will also be used by the hash-based module validation. Split it out from CONFIG_MODULE_SIG so it is usable by both. Signed-off-by: Thomas Wei=C3=9Fschuh --- include/linux/module.h | 8 ++++---- kernel/module/Kconfig | 6 +++++- kernel/module/main.c | 26 +++++++++++++++++++++++++- kernel/module/signing.c | 21 --------------------- 4 files changed, 34 insertions(+), 27 deletions(-) diff --git a/include/linux/module.h b/include/linux/module.h index b3a643435357986f3f9fe852260ca07f371cf86c..ccddab25d277da84d8c2866a9b4= ded7c18691c0d 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -451,7 +451,7 @@ struct module { const s32 *gpl_crcs; bool using_gplonly_symbols; =20 -#ifdef CONFIG_MODULE_SIG +#ifdef CONFIG_MODULE_SIG_POLICY /* Signature was verified. */ bool sig_ok; #endif @@ -928,14 +928,14 @@ static inline bool retpoline_module_ok(bool has_retpo= line) } #endif =20 -#ifdef CONFIG_MODULE_SIG +#ifdef CONFIG_MODULE_SIG_POLICY bool is_module_sig_enforced(void); =20 static inline bool module_sig_ok(struct module *module) { return module->sig_ok; } -#else /* !CONFIG_MODULE_SIG */ +#else /* !CONFIG_MODULE_SIG_POLICY */ static inline bool is_module_sig_enforced(void) { return false; @@ -945,7 +945,7 @@ static inline bool module_sig_ok(struct module *module) { return true; } -#endif /* CONFIG_MODULE_SIG */ +#endif /* CONFIG_MODULE_SIG_POLICY */ =20 #if defined(CONFIG_MODULES) && defined(CONFIG_KALLSYMS) int module_kallsyms_on_each_symbol(const char *modname, diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig index 7b329057997ad2ec310133ca84617d9bfcdb7e9f..a80de8d22efdd0f13b3eb579a8f= f1e69029d0694 100644 --- a/kernel/module/Kconfig +++ b/kernel/module/Kconfig @@ -210,9 +210,13 @@ config MODULE_SIG debuginfo strip done by some packagers (such as rpmbuild) and inclusion into an initramfs that wants the module size reduced. =20 +config MODULE_SIG_POLICY + def_bool y + depends on MODULE_SIG + config MODULE_SIG_FORCE bool "Require modules to be validly signed" - depends on MODULE_SIG + depends on MODULE_SIG_POLICY help Reject unsigned modules or signed modules for which we don't have a key. Without this, such modules will simply taint the kernel. diff --git a/kernel/module/main.c b/kernel/module/main.c index 5399c182b3cbed2dbeea0291f717f30358d8e7fc..8aa593fee22a227a482466dceda= 4a6b657b956e0 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -2367,7 +2367,7 @@ static void module_augment_kernel_taints(struct modul= e *mod, struct load_info *i mod->name); add_taint_module(mod, TAINT_TEST, LOCKDEP_STILL_OK); } -#ifdef CONFIG_MODULE_SIG +#ifdef CONFIG_MODULE_SIG_POLICY mod->sig_ok =3D info->sig_ok; if (!mod->sig_ok) { pr_notice_once("%s: module verification failed: signature " @@ -3779,3 +3779,27 @@ static int module_debugfs_init(void) } module_init(module_debugfs_init); #endif + +#ifdef CONFIG_MODULE_SIG_POLICY + +#undef MODULE_PARAM_PREFIX +#define MODULE_PARAM_PREFIX "module." + +static bool sig_enforce =3D IS_ENABLED(CONFIG_MODULE_SIG_FORCE); +module_param(sig_enforce, bool_enable_only, 0644); + +/* + * Export sig_enforce kernel cmdline parameter to allow other subsystems r= ely + * on that instead of directly to CONFIG_MODULE_SIG_FORCE config. + */ +bool is_module_sig_enforced(void) +{ + return sig_enforce; +} +EXPORT_SYMBOL(is_module_sig_enforced); + +void set_module_sig_enforced(void) +{ + sig_enforce =3D true; +} +#endif diff --git a/kernel/module/signing.c b/kernel/module/signing.c index a2ff4242e623d5d4e87d2f3d139d8620fb937579..e51920605da14771601327ea596= dad2e12400518 100644 --- a/kernel/module/signing.c +++ b/kernel/module/signing.c @@ -16,27 +16,6 @@ #include #include "internal.h" =20 -#undef MODULE_PARAM_PREFIX -#define MODULE_PARAM_PREFIX "module." - -static bool sig_enforce =3D IS_ENABLED(CONFIG_MODULE_SIG_FORCE); -module_param(sig_enforce, bool_enable_only, 0644); - -/* - * Export sig_enforce kernel cmdline parameter to allow other subsystems r= ely - * on that instead of directly to CONFIG_MODULE_SIG_FORCE config. - */ -bool is_module_sig_enforced(void) -{ - return sig_enforce; -} -EXPORT_SYMBOL(is_module_sig_enforced); - -void set_module_sig_enforced(void) -{ - sig_enforce =3D true; -} - /* * Verify the signature on a module. */ --=20 2.48.1 From nobody Sun Feb 8 10:44:30 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 8EF7314F9F7; Mon, 20 Jan 2025 17:45:41 +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=1737395145; cv=none; b=vFqLwNmz5jhQbnLBaJwBEHme0sIbIcXU7C/oeeYPZ9xhR3/zHGJdnsv/JBfTE84VRz14oOxkjX8wOHuenS+JqpV98jAroZ1sijPQfpjlvmKD40/Uv0FXHt0bom8CDCN2JmHAtAXQay02IibuBtO8LfV20PECDe/uMkqJ+hnERpc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737395145; c=relaxed/simple; bh=2c+/qat5XA+uZgTnXYB6U4MX9z83arDQnMX03CXPK+s=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=XZwlI/k8ItSESk6XZteU60tluwWl7yVnc939ITU+iiV/9J/VlVVTjaK2+ArtXOz8vGySrs+XBARNbNSLU/ySf4RvwS2IXbpgn7X6XdTP0Eoss71UdwvW24C449VpAM4W2mhyA4jjulNNhuRz1mFtMVmXj06a/8pUN5TIFBCzv+g= 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=D6vm50TG; 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="D6vm50TG" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1737395132; bh=2c+/qat5XA+uZgTnXYB6U4MX9z83arDQnMX03CXPK+s=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=D6vm50TGB1jQOvVpvu7AVmGxOJ8i/+4/65Bv6iluU7C8EYQQrOH39UaY6dC1AzjjP nWxk/HETwFk8oneQiIcS5MgkzElt8KvZXuW9ensotwXUSBbhx9yuzdA2lqQ4ICdLU6 kNyY0jOVuXIMQbmqVfCDEYnsbZC54hg2XJA2TeTw= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Mon, 20 Jan 2025 18:44:22 +0100 Subject: [PATCH v2 3/6] module: Move integrity checks into dedicated function 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: <20250120-module-hashes-v2-3-ba1184e27b7f@weissschuh.net> References: <20250120-module-hashes-v2-0-ba1184e27b7f@weissschuh.net> In-Reply-To: <20250120-module-hashes-v2-0-ba1184e27b7f@weissschuh.net> To: Masahiro Yamada , Nathan Chancellor , Nicolas Schier , Arnd Bergmann , Luis Chamberlain , Petr Pavlu , Sami Tolvanen , Daniel Gomez , Paul Moore , James Morris , "Serge E. Hallyn" , Jonathan Corbet Cc: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= , Arnout Engelen , Mattia Rizzolo , kpcyrd , 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, =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1737395132; l=2744; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=2c+/qat5XA+uZgTnXYB6U4MX9z83arDQnMX03CXPK+s=; b=drJV/f5DoXRznw97YMXiSAlAgXD0xKYklcfG5wuaksgRDgol3GdfurQjp2Nlf05qIoH+7uhEQ cHJr3OrmlnHCwOeUtuPxf13avRmM7nTITERDOcnenlp53V2e/zuXmmD X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= With the addition of hash-based integrity checking, the configuration matrix is easier to represent in a dedicated function and with explicit usage of IS_ENABLED(). Drop the now unnecessary stub for module_sig_check(). Signed-off-by: Thomas Wei=C3=9Fschuh --- kernel/module/internal.h | 7 ------- kernel/module/main.c | 18 ++++++++++++++---- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/kernel/module/internal.h b/kernel/module/internal.h index daef2be8390222c22220e2f168baa8d35ad531b9..c30abeefa60b884c4a69b1eb4f1= 123a4bbee4b47 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -333,14 +333,7 @@ int module_enable_text_rox(const struct module *mod); int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, char *secstrings, struct module *mod); =20 -#ifdef CONFIG_MODULE_SIG int module_sig_check(struct load_info *info, int flags); -#else /* !CONFIG_MODULE_SIG */ -static inline int module_sig_check(struct load_info *info, int flags) -{ - return 0; -} -#endif /* !CONFIG_MODULE_SIG */ =20 #ifdef CONFIG_DEBUG_KMEMLEAK void kmemleak_load_module(const struct module *mod, const struct load_info= *info); diff --git a/kernel/module/main.c b/kernel/module/main.c index 8aa593fee22a227a482466dceda4a6b657b956e0..c0ab5c37f9710a0091320c4d171= 275e63be9217e 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -3214,6 +3214,16 @@ static int early_mod_check(struct load_info *info, i= nt flags) return err; } =20 +static int module_integrity_check(struct load_info *info, int flags) +{ + int err =3D 0; + + if (IS_ENABLED(CONFIG_MODULE_SIG)) + err =3D module_sig_check(info, flags); + + return err; +} + /* * Allocate and load the module: note that size of section 0 is always * zero, and we rely on this for optional sections. @@ -3227,18 +3237,18 @@ static int load_module(struct load_info *info, cons= t char __user *uargs, char *after_dashes; =20 /* - * Do the signature check (if any) first. All that - * the signature check needs is info->len, it does + * Do the integrity checks (if any) first. All that + * they need is info->len, it does * not need any of the section info. That can be * set up later. This will minimize the chances * of a corrupt module causing problems before - * we even get to the signature check. + * we even get to the integrity check. * * The check will also adjust info->len by stripping * off the sig length at the end of the module, making * checks against info->len more correct. */ - err =3D module_sig_check(info, flags); + err =3D module_integrity_check(info, flags); if (err) goto free_copy; =20 --=20 2.48.1 From nobody Sun Feb 8 10:44:30 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 8EF3140C03; Mon, 20 Jan 2025 17:45:41 +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=1737395145; cv=none; b=PRMGgG59rjo7jSpCzWfKN3wh+GYbQkPycuTPWOGOYLP/4dqGEw1RokR2FOQl3X4qEyVwvM9hcSZL7ND+BzBbIRbOivrRAV2shaEXkdE6KPQZCJw52kO36NsyVQsuLvb8lJQIOTSxPLq4w41B9+vmvBl6K3FKT3Q/krRLpYuabok= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737395145; c=relaxed/simple; bh=PeJKb4hucwQgPB+ZRwTgF5LxeJD4ryt7mGorsuT2C9g=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tr1Xlh97jPW89YyscDAuTiQ9MiQldGnC1Kb1cJ45bN2Ep1qlE2XYzz4XrCzgUlX2fA1ogWltS9wXP/qGY37pJVAz+BdXbvIeSHEn6jVKoHgZ0RhCQsguH0jdhu+J5S4MCw/rLNRaX6Yqbi/P7w/IRW7DM5CoTz/syaSmI4OMKxE= 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=fUAhGFvi; 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="fUAhGFvi" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1737395132; bh=PeJKb4hucwQgPB+ZRwTgF5LxeJD4ryt7mGorsuT2C9g=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=fUAhGFvieGibWp2VJmcpy+GwxnXo2KS7qPDW+BktqS1oLNeoxcP2ktKAa1UZ37IdP zjg77gozyVh6X8wJlH94CVtO+kLJBVEEenN88DK0Oa2Sjf71zD4SKKF+NasNo11hGf GL0p+PatwRzAfikNHczJomBPMnodvreHB6hiWkUY= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Mon, 20 Jan 2025 18:44:23 +0100 Subject: [PATCH v2 4/6] module: Move lockdown check into generic module loader 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: <20250120-module-hashes-v2-4-ba1184e27b7f@weissschuh.net> References: <20250120-module-hashes-v2-0-ba1184e27b7f@weissschuh.net> In-Reply-To: <20250120-module-hashes-v2-0-ba1184e27b7f@weissschuh.net> To: Masahiro Yamada , Nathan Chancellor , Nicolas Schier , Arnd Bergmann , Luis Chamberlain , Petr Pavlu , Sami Tolvanen , Daniel Gomez , Paul Moore , James Morris , "Serge E. Hallyn" , Jonathan Corbet Cc: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= , Arnout Engelen , Mattia Rizzolo , kpcyrd , 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, =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1737395132; l=1576; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=PeJKb4hucwQgPB+ZRwTgF5LxeJD4ryt7mGorsuT2C9g=; b=F83ENlvy7TmkkAZ5zKo3BpFCXUyf+IXj0q3zgdOerpkiq/H1Wyk9IbPP1VIPrf/y3PCF4tE0t DcnM4fQ/FUzD7gs+b3l4suCtjYHdrwExXswam8suyFL4bDqqqwyn5+g X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= The lockdown check buried in module_sig_check() will not compose well with the introduction of hash-based module validation. Move it into module_integrity_check() which will work better. Signed-off-by: Thomas Wei=C3=9Fschuh --- kernel/module/main.c | 6 +++++- kernel/module/signing.c | 3 +-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/kernel/module/main.c b/kernel/module/main.c index c0ab5c37f9710a0091320c4d171275e63be9217e..effe1db02973d4f60ff6cbc0d3b= 5241a3576fa3e 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -3221,7 +3221,11 @@ static int module_integrity_check(struct load_info *= info, int flags) if (IS_ENABLED(CONFIG_MODULE_SIG)) err =3D module_sig_check(info, flags); =20 - return err; + if (err) + return err; + if (info->sig_ok) + return 0; + return security_locked_down(LOCKDOWN_MODULE_SIGNATURE); } =20 /* diff --git a/kernel/module/signing.c b/kernel/module/signing.c index e51920605da14771601327ea596dad2e12400518..029e1ef6f0e369fd48e8c81154b= 6c697ad7a6249 100644 --- a/kernel/module/signing.c +++ b/kernel/module/signing.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include "internal.h" @@ -100,5 +99,5 @@ int module_sig_check(struct load_info *info, int flags) return -EKEYREJECTED; } =20 - return security_locked_down(LOCKDOWN_MODULE_SIGNATURE); + return 0; } --=20 2.48.1 From nobody Sun Feb 8 10:44:30 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 8EFCE1DFE14; Mon, 20 Jan 2025 17:45:41 +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=1737395144; cv=none; b=fWNE3xaEsCe8lKQNaXCUkSQu5nW80OpTwezd4J6iFUQUl2/JkxttyH6S2nsSJ+GeqqDXcX4iFDULIykBTqHCbgFjf6ilsfvrc8gg5Q9BEm9edQGKFHQjxvH78akIif20brdz98sIdXcLq28bvnL5AcGQBObQn5YeLLtSmQm9v2M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737395144; c=relaxed/simple; bh=eFE8eKbO4pWZaL11j78KVv6utQAl0cUhH525xL6hI5o=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=YoWsUOwYXZSUoW321LP3wInegDIXWnBH72R8BK3R5ej0DTReC0jChPuglvJrtEdIZeOgsFG03O4N1FJ+d0OjelSPurnNAtsgo3z+Gm9LpMTCayOJtAXJhD8DGPCeyoBLNQWswuMdsYNZzpUwikc2gMqtuwQZ+VTwAdX2IMwFW8w= 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=pvkeEPHr; 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="pvkeEPHr" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1737395133; bh=eFE8eKbO4pWZaL11j78KVv6utQAl0cUhH525xL6hI5o=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=pvkeEPHrKRw+yfyKuOPjl3X46G0uP5F+Wg36ErvPQhBHP6vUXdrpZjXrw9NcMcmtK pnRHrNi0dbUlvHnhfakwdOPhXl6r71BLvGs7jYe6Hw9dYkW0nQJ9PWdiIw+7eNvEY/ 7mh2ctMUYT94pg0iN2/DrP7wCoVBtiNxN1T3a8IY= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Mon, 20 Jan 2025 18:44:24 +0100 Subject: [PATCH v2 5/6] lockdown: Make the relationship to MODULE_SIG a dependency 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: <20250120-module-hashes-v2-5-ba1184e27b7f@weissschuh.net> References: <20250120-module-hashes-v2-0-ba1184e27b7f@weissschuh.net> In-Reply-To: <20250120-module-hashes-v2-0-ba1184e27b7f@weissschuh.net> To: Masahiro Yamada , Nathan Chancellor , Nicolas Schier , Arnd Bergmann , Luis Chamberlain , Petr Pavlu , Sami Tolvanen , Daniel Gomez , Paul Moore , James Morris , "Serge E. Hallyn" , Jonathan Corbet Cc: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= , Arnout Engelen , Mattia Rizzolo , kpcyrd , 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, =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1737395132; l=874; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=eFE8eKbO4pWZaL11j78KVv6utQAl0cUhH525xL6hI5o=; b=8dA83wKAd3Hc6tOftrWqF/p7g+4ibEoT3lyBhHTbTQ7dsE2V7oG4U+strj5pxZV+ykpvxhAI6 AgAp3mLUgFkCx2AaxTMMLuYhpt+4Znru3wpqIF3NmQX8OMDaR7EOI78 X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= The new hash-based module integrity checking will also be able to satisfy the requirements of lockdown. Such an alternative is not representable with "select", so use "depends on" instead. Signed-off-by: Thomas Wei=C3=9Fschuh --- security/lockdown/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig index e84ddf48401010bcc0829a32db58e6f12bfdedcb..155959205b8eac2c85897a8c4c8= b7ec471156706 100644 --- a/security/lockdown/Kconfig +++ b/security/lockdown/Kconfig @@ -1,7 +1,7 @@ config SECURITY_LOCKDOWN_LSM bool "Basic module for enforcing kernel lockdown" depends on SECURITY - select MODULE_SIG if MODULES + depends on !MODULES || MODULE_SIG help Build support for an LSM that enforces a coarse kernel lockdown behaviour. --=20 2.48.1 From nobody Sun Feb 8 10:44:30 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 9DD7D1F03D0; Mon, 20 Jan 2025 17:45:46 +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=1737395149; cv=none; b=JsTxl9z4HK3yz39TNFYyQKTmhAvYoULAEdohPr0WJX9gOJKSoB27ToLlk0IqHJZ7bjDHfR4GCkIufKJvhJD7FHfFkpXIblx/6XB9rjB7R5fzSfPK1osbUUfkog2mul0FiFZ2jtY9eKfLouwZ1DiVSEeUxiR6MSBUbR6r9aXqC1A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737395149; c=relaxed/simple; bh=MdKjsanauiC7LwdkZFfsgUbSTeQZc+J9ZaaglNxxsks=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=tu6b7zp8RViZIY6WE8isYjG3NpUft6UiRgEn9XoicJPhVMP+1JDVHHicNjm+SOpN0fQV7krrqB2P84ReqY3uHowwFLq5nuXyscR7s1ss3CnTETWcuhKef+4zpHEhyS95g6UpEsznQ0iEjNc4qNjM4Pcv/42qKzvqYU47O7PPu1M= 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=Di/M6gV2; 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="Di/M6gV2" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=weissschuh.net; s=mail; t=1737395133; bh=MdKjsanauiC7LwdkZFfsgUbSTeQZc+J9ZaaglNxxsks=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Di/M6gV2PZR/Y+ULPHNpx2nP0AYRmpRur97hFwzhHG9qZT82EnocNOEeA3rqp3lz0 h2+5CUwBdmHujmMocjg40PdHqjw5a1g3xHKKAaNvJi5l5iniwzPm4ALjx8K8HosPA8 5uUlyHHmdUAigVH4CGaYEfN3OXur5Xhu8uUM9F6U= From: =?utf-8?q?Thomas_Wei=C3=9Fschuh?= Date: Mon, 20 Jan 2025 18:44:25 +0100 Subject: [PATCH v2 6/6] module: Introduce hash-based integrity checking 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: <20250120-module-hashes-v2-6-ba1184e27b7f@weissschuh.net> References: <20250120-module-hashes-v2-0-ba1184e27b7f@weissschuh.net> In-Reply-To: <20250120-module-hashes-v2-0-ba1184e27b7f@weissschuh.net> To: Masahiro Yamada , Nathan Chancellor , Nicolas Schier , Arnd Bergmann , Luis Chamberlain , Petr Pavlu , Sami Tolvanen , Daniel Gomez , Paul Moore , James Morris , "Serge E. Hallyn" , Jonathan Corbet Cc: =?utf-8?q?Fabian_Gr=C3=BCnbichler?= , Arnout Engelen , Mattia Rizzolo , kpcyrd , 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, =?utf-8?q?Thomas_Wei=C3=9Fschuh?= X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1737395132; l=14935; i=linux@weissschuh.net; s=20221212; h=from:subject:message-id; bh=MdKjsanauiC7LwdkZFfsgUbSTeQZc+J9ZaaglNxxsks=; b=5IcmE9REX+FAANRF1h1BOnurKOwOaYMYqcpINOm6mCBcRkcTSJcMrGzt0fX37CpcqtYiEvLc0 1QQkiSWcpjND1eqQ23aAdahsCJmu7W0HC8zogLdLsmo3NKJQWBIePjD X-Developer-Key: i=linux@weissschuh.net; a=ed25519; pk=KcycQgFPX2wGR5azS7RhpBqedglOZVgRPfdFSPB1LNw= The current signature-based module integrity checking has some drawbacks in combination with reproducible builds: Either the module signing key is generated at build time, which makes the build unreproducible, or a static key is used, which precludes rebuilds by third parties and makes the whole build and packaging process much more complicated. Introduce a new mechanism to ensure only well-known modules are loaded by embedding a list of hashes of all modules built as part of the full kernel build into vmlinux. Non-builtin modules can be validated as before through signatures. Signed-off-by: Thomas Wei=C3=9Fschuh --- .gitignore | 1 + Documentation/kbuild/reproducible-builds.rst | 5 ++- Makefile | 8 ++++- include/asm-generic/vmlinux.lds.h | 11 ++++++ include/linux/module_hashes.h | 17 +++++++++ kernel/module/Kconfig | 17 ++++++++- kernel/module/Makefile | 1 + kernel/module/hashes.c | 52 ++++++++++++++++++++++++= ++++ kernel/module/internal.h | 1 + kernel/module/main.c | 6 ++++ scripts/Makefile.modfinal | 6 ++++ scripts/Makefile.vmlinux | 5 +++ scripts/link-vmlinux.sh | 25 ++++++++++++- scripts/module-hashes.sh | 26 ++++++++++++++ security/lockdown/Kconfig | 2 +- 15 files changed, 178 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 6839cf84acda0d2d3c236a2e42b0cb0fe1b14965..7c40151c3f5d0c15ac04cead5f2= 1c291a98d779f 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ *.gz *.i *.ko +*.ko.hash *.lex.c *.ll *.lst diff --git a/Documentation/kbuild/reproducible-builds.rst b/Documentation/k= build/reproducible-builds.rst index f2dcc39044e66ddd165646e0b51ccb0209aca7dd..6a742ad745113a9267223b33810= dbc7218c47d4c 100644 --- a/Documentation/kbuild/reproducible-builds.rst +++ b/Documentation/kbuild/reproducible-builds.rst @@ -79,7 +79,10 @@ generate a different temporary key for each build, resul= ting in the modules being unreproducible. However, including a signing key with your source would presumably defeat the purpose of signing modules. =20 -One approach to this is to divide up the build process so that the +Instead ``CONFIG_MODULE_HASHES`` can be used to embed a static list +of valid modules to load. + +Another approach to this is to divide up the build process so that the unreproducible parts can be treated as sources: =20 1. Generate a persistent signing key. Add the certificate for the key diff --git a/Makefile b/Makefile index b9464c88ac7230518a756bff5e6c5c8871cc5058..fc862ffd2df843c0b68bebc8f55= 4b88850ba1541 100644 --- a/Makefile +++ b/Makefile @@ -1535,8 +1535,10 @@ endif # is an exception. ifdef CONFIG_DEBUG_INFO_BTF_MODULES KBUILD_BUILTIN :=3D 1 +ifndef CONFIG_MODULE_HASHES modules: vmlinux endif +endif =20 modules: modules_prepare =20 @@ -1916,7 +1918,11 @@ modules.order: $(build-dir) # KBUILD_MODPOST_NOFINAL can be set to skip the final link of modules. # This is solely useful to speed up test compiles. modules: modpost -ifneq ($(KBUILD_MODPOST_NOFINAL),1) +ifdef CONFIG_MODULE_HASHES +ifeq ($(MODULE_HASHES_MODPOST_FINAL), 1) + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal +endif +else ifneq ($(KBUILD_MODPOST_NOFINAL),1) $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modfinal endif =20 diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinu= x.lds.h index 54504013c74915c2ed923fb3afde024a69cdae6b..aebea528aac3d7209bcee12c25f= 750ab0f7576a5 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -486,6 +486,8 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPELL= ER_CLANG) \ PRINTK_INDEX \ \ + MODULE_HASHES \ + \ /* Kernel symbol table: Normal symbols */ \ __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ __start___ksymtab =3D .; \ @@ -895,6 +897,15 @@ defined(CONFIG_AUTOFDO_CLANG) || defined(CONFIG_PROPEL= LER_CLANG) #define PRINTK_INDEX #endif =20 +#ifdef CONFIG_MODULE_HASHES +#define MODULE_HASHES \ + .module_hashes : AT(ADDR(.module_hashes) - LOAD_OFFSET) { \ + BOUNDED_SECTION_BY(.module_hashes, _module_hashes) \ + } +#else +#define MODULE_HASHES +#endif + /* * Discard .note.GNU-stack, which is emitted as PROGBITS by the compiler. * Otherwise, the type of .notes section would become PROGBITS instead of = NOTES. diff --git a/include/linux/module_hashes.h b/include/linux/module_hashes.h new file mode 100644 index 0000000000000000000000000000000000000000..5f2f0546e3875e6bc73bdd53aeb= aada7371b7f79 --- /dev/null +++ b/include/linux/module_hashes.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _LINUX_MODULE_HASHES_H +#define _LINUX_MODULE_HASHES_H + +#include +#include +#include + +#define __module_hashes_section __section(".module_hashes") +#define MODULE_HASHES_HASH_SIZE SHA256_DIGEST_SIZE + +extern const u8 module_hashes[][MODULE_HASHES_HASH_SIZE]; + +extern const typeof(module_hashes[0]) __start_module_hashes, __stop_module= _hashes; + +#endif /* _LINUX_MODULE_HASHES_H */ diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig index a80de8d22efdd0f13b3eb579a8ff1e69029d0694..cdd30b9a08d8cdf3ec0595b5e41= 4265b869d343e 100644 --- a/kernel/module/Kconfig +++ b/kernel/module/Kconfig @@ -212,7 +212,7 @@ config MODULE_SIG =20 config MODULE_SIG_POLICY def_bool y - depends on MODULE_SIG + depends on MODULE_SIG || MODULE_HASHES =20 config MODULE_SIG_FORCE bool "Require modules to be validly signed" @@ -348,6 +348,21 @@ config MODULE_DECOMPRESS =20 If unsure, say N. =20 +config MODULE_HASHES + bool "Module hash validation" + depends on $(success,cksum --algorithm sha256 --raw /dev/null) + select CRYPTO_LIB_SHA256 + help + Validate modules by their hashes. + Only modules built together with the main kernel image can be + validated that way. + + This is a reproducible-build compatible alternative to a build-time + generated module keyring, as enabled by + CONFIG_MODULE_SIG_KEY=3Dcerts/signing_key.pem. + + Also see the warning in MODULE_SIG about stripping modules. + config MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS bool "Allow loading of modules with missing namespace imports" help diff --git a/kernel/module/Makefile b/kernel/module/Makefile index 50ffcc413b54504db946af4dce3b41dc4aece1a5..6fe0c14ca5a05b49c1161fcfa8a= aa130f89b70e1 100644 --- a/kernel/module/Makefile +++ b/kernel/module/Makefile @@ -23,3 +23,4 @@ obj-$(CONFIG_KGDB_KDB) +=3D kdb.o obj-$(CONFIG_MODVERSIONS) +=3D version.o obj-$(CONFIG_MODULE_UNLOAD_TAINT_TRACKING) +=3D tracking.o obj-$(CONFIG_MODULE_STATS) +=3D stats.o +obj-$(CONFIG_MODULE_HASHES) +=3D hashes.o diff --git a/kernel/module/hashes.c b/kernel/module/hashes.c new file mode 100644 index 0000000000000000000000000000000000000000..1aa49767a39b4e0c495b17d3f2e= dcb5a6ceb839e --- /dev/null +++ b/kernel/module/hashes.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#define pr_fmt(fmt) "module/hash: " fmt + +#include +#include +#include +#include +#include "internal.h" + +static inline size_t module_hashes_count(void) +{ + return (__stop_module_hashes - __start_module_hashes) / MODULE_HASHES_HAS= H_SIZE; +} + +static __init __maybe_unused int module_hashes_init(void) +{ + size_t num_hashes =3D module_hashes_count(); + int num_width =3D (intlog10(num_hashes) >> 24) + 1; + size_t i; + + pr_debug("Known hashes (%zu):\n", num_hashes); + + for (i =3D 0; i < num_hashes; i++) + pr_debug("%*zu %*phN\n", num_width, i, + (int)sizeof(module_hashes[i]), module_hashes[i]); + + return 0; +} + +#if IS_ENABLED(CONFIG_MODULE_DEBUG) +early_initcall(module_hashes_init); +#endif + +int module_hash_check(struct load_info *info, int flags) +{ + u8 digest[MODULE_HASHES_HASH_SIZE]; + size_t i; + + sha256((const u8 *)info->hdr, info->len, digest); + + for (i =3D 0; i < module_hashes_count(); i++) { + if (memcmp(module_hashes[i], digest, MODULE_HASHES_HASH_SIZE) =3D=3D 0) { + pr_debug("allow %*phN\n", (int)sizeof(digest), digest); + info->sig_ok =3D true; + return 0; + } + } + + pr_debug("block %*phN\n", (int)sizeof(digest), digest); + return -ENOKEY; +} diff --git a/kernel/module/internal.h b/kernel/module/internal.h index c30abeefa60b884c4a69b1eb4f1123a4bbee4b47..9c927c212f862fff7000f1cfac3= c7e391a2390ac 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -334,6 +334,7 @@ int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr= *sechdrs, char *secstrings, struct module *mod); =20 int module_sig_check(struct load_info *info, int flags); +int module_hash_check(struct load_info *info, int flags); =20 #ifdef CONFIG_DEBUG_KMEMLEAK void kmemleak_load_module(const struct module *mod, const struct load_info= *info); diff --git a/kernel/module/main.c b/kernel/module/main.c index effe1db02973d4f60ff6cbc0d3b5241a3576fa3e..094ace81d795711b56d12a2abc7= 5ea35449c8300 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -3218,6 +3218,12 @@ static int module_integrity_check(struct load_info *= info, int flags) { int err =3D 0; =20 + if (IS_ENABLED(CONFIG_MODULE_HASHES)) { + err =3D module_hash_check(info, flags); + if (!err) + return 0; + } + if (IS_ENABLED(CONFIG_MODULE_SIG)) err =3D module_sig_check(info, flags); =20 diff --git a/scripts/Makefile.modfinal b/scripts/Makefile.modfinal index 5d01b553ec9a4565c8e5a6edd05665c409003bc1..080b4fc3a9ba5036b45f04a7e79= f2fc02364f93a 100644 --- a/scripts/Makefile.modfinal +++ b/scripts/Makefile.modfinal @@ -43,6 +43,9 @@ quiet_cmd_btf_ko =3D BTF [M] $@ $(RESOLVE_BTFIDS) -b $(objtree)/vmlinux $@; \ fi; =20 +quiet_cmd_cksum_ko =3D + cmd_cksum_ko =3D cksum --algorithm sha256 --raw $@ > $@.hash + # Same as newer-prereqs, but allows to exclude specified extra dependencies newer_prereqs_except =3D $(filter-out $(PHONY) $(1),$?) =20 @@ -57,6 +60,9 @@ if_changed_except =3D $(if $(call newer_prereqs_except,$(= 2))$(cmd-check), \ ifdef CONFIG_DEBUG_INFO_BTF_MODULES +$(if $(newer-prereqs),$(call cmd,btf_ko)) endif +ifdef CONFIG_MODULE_HASHES + $(call cmd,cksum_ko) +endif =20 targets +=3D $(modules:%.o=3D%.ko) $(modules:%.o=3D%.mod.o) .module-common= .o =20 diff --git a/scripts/Makefile.vmlinux b/scripts/Makefile.vmlinux index 873caaa553134e09d034e0c4e0ac7f07c9e3f31b..4b6ba03cdd5e4faad30a0b53340= 7955c542c7a20 100644 --- a/scripts/Makefile.vmlinux +++ b/scripts/Makefile.vmlinux @@ -79,6 +79,11 @@ ifdef CONFIG_DEBUG_INFO_BTF vmlinux: $(RESOLVE_BTFIDS) endif =20 +ifdef CONFIG_MODULE_HASHES +vmlinux: $(srctree)/scripts/module-hashes.sh +vmlinux: modules.order +endif + # module.builtin.ranges # ------------------------------------------------------------------------= --- ifdef CONFIG_BUILTIN_MODULE_RANGES diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh index 803c8d6f35a7f29fb68b29afa8546f4dde0bd4cb..db072e4e5d6581453a009a9e837= 042ba28a138ce 100755 --- a/scripts/link-vmlinux.sh +++ b/scripts/link-vmlinux.sh @@ -104,7 +104,7 @@ vmlinux_link() ${ld} ${ldflags} -o ${output} \ ${wl}--whole-archive ${objs} ${wl}--no-whole-archive \ ${wl}--start-group ${libs} ${wl}--end-group \ - ${kallsymso} ${btf_vmlinux_bin_o} ${arch_vmlinux_o} ${ldlibs} + ${kallsymso} ${btf_vmlinux_bin_o} ${module_hashes_o} ${arch_vmlinux_o} $= {ldlibs} } =20 # generate .BTF typeinfo from DWARF debuginfo @@ -215,6 +215,7 @@ fi =20 btf_vmlinux_bin_o=3D kallsymso=3D +module_hashes_o=3D strip_debug=3D =20 if is_enabled CONFIG_KALLSYMS; then @@ -222,6 +223,17 @@ if is_enabled CONFIG_KALLSYMS; then kallsyms .tmp_vmlinux0.syms .tmp_vmlinux0.kallsyms fi =20 +if is_enabled CONFIG_MODULE_HASHES; then + # At this point the hashes are still wrong. + # This step reserves the exact amount of space for the objcopy step + # after BTF generation. + ${srctree}/scripts/module-hashes.sh prealloc > .tmp_module_hashes.c + module_hashes_o=3D.tmp_module_hashes.o + info CC ${module_hashes_o} + ${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} ${KBUILD_CFLAG= S} \ + ${KBUILD_CFLAGS_KERNEL} -c -o "${module_hashes_o}" ".tmp_module_hashes.c" +fi + if is_enabled CONFIG_KALLSYMS || is_enabled CONFIG_DEBUG_INFO_BTF; then =20 # The kallsyms linking does not need debug symbols, but the BTF does. @@ -302,6 +314,17 @@ if is_enabled CONFIG_BUILDTIME_TABLE_SORT; then fi fi =20 +if is_enabled CONFIG_MODULE_HASHES; then + info MAKE modules + ${MAKE} -f Makefile MODULE_HASHES_MODPOST_FINAL=3D1 modules + ${srctree}/scripts/module-hashes.sh > .tmp_module_hashes.c + info CC ${module_hashes_o} + ${CC} ${NOSTDINC_FLAGS} ${LINUXINCLUDE} ${KBUILD_CPPFLAGS} ${KBUILD_CFLAG= S} \ + ${KBUILD_CFLAGS_KERNEL} -c -o "${module_hashes_o}" ".tmp_module_hashes.c" + ${OBJCOPY} --dump-section .module_hashes=3D.tmp_module_hashes.bin ${modul= e_hashes_o} + ${OBJCOPY} --update-section .module_hashes=3D.tmp_module_hashes.bin vmlin= ux +fi + # step a (see comment above) if is_enabled CONFIG_KALLSYMS; then if ! cmp -s System.map "${kallsyms_sysmap}"; then diff --git a/scripts/module-hashes.sh b/scripts/module-hashes.sh new file mode 100755 index 0000000000000000000000000000000000000000..120ce924105c51cdd7a704cbec7= e5fa356f9ce1a --- /dev/null +++ b/scripts/module-hashes.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later + +set -e +set -u +set -o pipefail + +prealloc=3D"${1:-}" + +echo "#include " +echo +echo "const u8 module_hashes[][MODULE_HASHES_HASH_SIZE] __module_hashes_se= ction =3D {" + +for mod in $(< modules.order); do + mod=3D"${mod/%.o/.ko}" + if [ "$prealloc" =3D "prealloc" ]; then + modhash=3D"" + else + modhash=3D"$(cat "$mod".hash | hexdump -v -e '"0x" 1/1 "%02x, "')" + fi + echo -e "\t/* $mod */" + echo -e "\t{ $modhash}," + echo +done + +echo "};" diff --git a/security/lockdown/Kconfig b/security/lockdown/Kconfig index 155959205b8eac2c85897a8c4c8b7ec471156706..60b240e3ef1f9609e3f3241befc= 0bbc7e4a3db74 100644 --- a/security/lockdown/Kconfig +++ b/security/lockdown/Kconfig @@ -1,7 +1,7 @@ config SECURITY_LOCKDOWN_LSM bool "Basic module for enforcing kernel lockdown" depends on SECURITY - depends on !MODULES || MODULE_SIG + depends on !MODULES || MODULE_SIG || MODULE_HASHES help Build support for an LSM that enforces a coarse kernel lockdown behaviour. --=20 2.48.1