From patchwork Tue Feb 22 10:38:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Leroy X-Patchwork-Id: 12754858 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 80CC1C433EF for ; Tue, 22 Feb 2022 10:39:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231300AbiBVKjn (ORCPT ); Tue, 22 Feb 2022 05:39:43 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44730 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230313AbiBVKjm (ORCPT ); Tue, 22 Feb 2022 05:39:42 -0500 Received: from pegase2.c-s.fr (pegase2.c-s.fr [93.17.235.10]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6D8BE1520E6; Tue, 22 Feb 2022 02:39:17 -0800 (PST) Received: from localhost (mailhub3.si.c-s.fr [172.26.127.67]) by localhost (Postfix) with ESMTP id 4K2wdc0fVsz9sT9; Tue, 22 Feb 2022 11:39:16 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase2.c-s.fr ([172.26.127.65]) by localhost (pegase2.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2O9RG79dWjM2; Tue, 22 Feb 2022 11:39:16 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase2.c-s.fr (Postfix) with ESMTP id 4K2wdb6RWSz9sT4; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id C9B608B77C; Tue, 22 Feb 2022 11:39:15 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id wfwOKewn2RBv; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from PO20335.IDSI0.si.c-s.fr (unknown [172.25.230.108]) by messagerie.si.c-s.fr (Postfix) with ESMTP id A445D8B764; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 21MAd66I1076205 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 22 Feb 2022 11:39:06 +0100 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 21MAd6pm1076204; Tue, 22 Feb 2022 11:39:06 +0100 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Aaron Tomlin , Luis Chamberlain , linux-modules@vger.kernel.org Cc: Christophe Leroy , linux-kernel@vger.kernel.org Subject: [PATCH v1 1/6] module: Have kernel/module/ dedicated to CONFIG_MODULES Date: Tue, 22 Feb 2022 11:38:55 +0100 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1645526317; l=2248; s=20211009; h=from:subject:message-id; bh=U293g+lTgs0inrdbxXPK4v+1d094S6shdcVBALPrnlM=; b=eS6Qa+cXgZONSOWXof3UZfhfQvOyNb0IZDb3SEsE87arTGp2VLmxbBJKhpokG3Rxc27SrWQTKdnT rHGJ9CLnDY0czeMhIdpGMQYH+XdLne82cw6tJNtjXYeWSny1BUYJ X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Precedence: bulk List-ID: Move signature.c back into kernel/ because it is used by more than modules. Then build kernel/module/ only when CONFIG_MODULES is selected. Signed-off-by: Christophe Leroy --- Ideally this patch should be squashed in Aaron's series patch 1 --- kernel/Makefile | 3 ++- kernel/module/Makefile | 5 +---- kernel/{module/signature.c => module_signature.c} | 0 3 files changed, 3 insertions(+), 5 deletions(-) rename kernel/{module/signature.c => module_signature.c} (100%) diff --git a/kernel/Makefile b/kernel/Makefile index 04cb6932c0d3..717075b65deb 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -52,7 +52,7 @@ obj-y += rcu/ obj-y += livepatch/ obj-y += dma/ obj-y += entry/ -obj-y += module/ +obj-$(CONFIG_MODULES) += module/ obj-$(CONFIG_KCMP) += kcmp.o obj-$(CONFIG_FREEZER) += freezer.o @@ -66,6 +66,7 @@ ifneq ($(CONFIG_SMP),y) obj-y += up.o endif obj-$(CONFIG_UID16) += uid16.o +obj-$(CONFIG_MODULE_SIG_FORMAT) += module_signature.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o obj-$(CONFIG_CRASH_CORE) += crash_core.o diff --git a/kernel/module/Makefile b/kernel/module/Makefile index b57953bd47eb..5fe90d246fcc 100644 --- a/kernel/module/Makefile +++ b/kernel/module/Makefile @@ -7,12 +7,10 @@ # and produce insane amounts of uninteresting coverage. KCOV_INSTRUMENT_main.o := n -obj-$(CONFIG_MODULES) += main.o +obj-y += main.o obj-$(CONFIG_MODULE_DECOMPRESS) += decompress.o obj-$(CONFIG_MODULE_SIG) += signing.o -obj-$(CONFIG_MODULE_SIG_FORMAT) += signature.o obj-$(CONFIG_LIVEPATCH) += livepatch.o -ifdef CONFIG_MODULES obj-$(CONFIG_MODULES_TREE_LOOKUP) += tree_lookup.o obj-$(CONFIG_STRICT_MODULE_RWX) += strict_rwx.o obj-$(CONFIG_DEBUG_KMEMLEAK) += debug_kmemleak.o @@ -20,4 +18,3 @@ obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-$(CONFIG_PROC_FS) += procfs.o obj-$(CONFIG_SYSFS) += sysfs.o obj-$(CONFIG_MODVERSIONS) += version.o -endif diff --git a/kernel/module/signature.c b/kernel/module_signature.c similarity index 100% rename from kernel/module/signature.c rename to kernel/module_signature.c From patchwork Tue Feb 22 10:38:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Leroy X-Patchwork-Id: 12754860 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id ECC6AC433FE for ; Tue, 22 Feb 2022 10:39:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231310AbiBVKjv (ORCPT ); Tue, 22 Feb 2022 05:39:51 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44918 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231327AbiBVKju (ORCPT ); Tue, 22 Feb 2022 05:39:50 -0500 Received: from pegase2.c-s.fr (pegase2.c-s.fr [93.17.235.10]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 412D715A23B; Tue, 22 Feb 2022 02:39:24 -0800 (PST) Received: from localhost (mailhub3.si.c-s.fr [172.26.127.67]) by localhost (Postfix) with ESMTP id 4K2wdf1WdZz9sT2; Tue, 22 Feb 2022 11:39:18 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase2.c-s.fr ([172.26.127.65]) by localhost (pegase2.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id kng-gG1vZyg9; Tue, 22 Feb 2022 11:39:18 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase2.c-s.fr (Postfix) with ESMTP id 4K2wdb6R6Jz9sT3; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id CBA888B781; Tue, 22 Feb 2022 11:39:15 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id 4ZqC7DO4sAS9; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from PO20335.IDSI0.si.c-s.fr (unknown [172.25.230.108]) by messagerie.si.c-s.fr (Postfix) with ESMTP id A45DA8B775; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 21MAd6dC1076210 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 22 Feb 2022 11:39:06 +0100 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 21MAd6Og1076209; Tue, 22 Feb 2022 11:39:06 +0100 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Aaron Tomlin , Luis Chamberlain , linux-modules@vger.kernel.org Cc: Christophe Leroy , linux-kernel@vger.kernel.org Subject: [PATCH v1 2/6] module: Move module's Kconfig item in kernel/module/ Date: Tue, 22 Feb 2022 11:38:56 +0100 Message-Id: <827e2065b5920d52dd18fbca5b302a7c26a5032a.1645526008.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1645526317; l=21654; s=20211009; h=from:subject:message-id; bh=f1WYkeljkpqDrXVJoanofP6w+qtYTk0izurDmHmfG8g=; b=y9VrJUbu1/aM4anwDdI5WQd2AMEt/wf0e2RhsvSUk0zrDsTuaHyBeVN8Sn9UtgCp4RE3BOgK/ck/ ehMYrDD6DSYYhbLbiuDTSFzM/Mb2GXBmEINdJ0IZS5eAu/AdB5Hf X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Precedence: bulk List-ID: In init/Kconfig, the part dedicated to modules is quite large. Move it into a dedicated Kconfig in kernel/module/ Signed-off-by: Christophe Leroy --- init/Kconfig | 286 +----------------------------------------- kernel/module/Kconfig | 286 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 287 insertions(+), 285 deletions(-) create mode 100644 kernel/module/Kconfig diff --git a/init/Kconfig b/init/Kconfig index e9119bf54b1f..1c8828493385 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -2064,291 +2064,7 @@ config MODULE_SIG_FORMAT def_bool n select SYSTEM_DATA_VERIFICATION -menuconfig MODULES - bool "Enable loadable module support" - modules - help - Kernel modules are small pieces of compiled code which can - be inserted in the running kernel, rather than being - permanently built into the kernel. You use the "modprobe" - tool to add (and sometimes remove) them. If you say Y here, - many parts of the kernel can be built as modules (by - answering M instead of Y where indicated): this is most - useful for infrequently used options which are not required - for booting. For more information, see the man pages for - modprobe, lsmod, modinfo, insmod and rmmod. - - If you say Y here, you will need to run "make - modules_install" to put the modules under /lib/modules/ - where modprobe can find them (you may need to be root to do - this). - - If unsure, say Y. - -if MODULES - -config MODULE_FORCE_LOAD - bool "Forced module loading" - default n - help - Allow loading of modules without version information (ie. modprobe - --force). Forced module loading sets the 'F' (forced) taint flag and - is usually a really bad idea. - -config MODULE_UNLOAD - bool "Module unloading" - help - Without this option you will not be able to unload any - modules (note that some modules may not be unloadable - anyway), which makes your kernel smaller, faster - and simpler. If unsure, say Y. - -config MODULE_FORCE_UNLOAD - bool "Forced module unloading" - depends on MODULE_UNLOAD - help - This option allows you to force a module to unload, even if the - kernel believes it is unsafe: the kernel will remove the module - without waiting for anyone to stop using it (using the -f option to - rmmod). This is mainly for kernel developers and desperate users. - If unsure, say N. - -config MODVERSIONS - bool "Module versioning support" - help - Usually, you have to use modules compiled with your kernel. - Saying Y here makes it sometimes possible to use modules - compiled for different kernels, by adding enough information - to the modules to (hopefully) spot any changes which would - make them incompatible with the kernel you are running. If - unsure, say N. - -config ASM_MODVERSIONS - bool - default HAVE_ASM_MODVERSIONS && MODVERSIONS - help - This enables module versioning for exported symbols also from - assembly. This can be enabled only when the target architecture - supports it. - -config MODULE_REL_CRCS - bool - depends on MODVERSIONS - -config MODULE_SRCVERSION_ALL - bool "Source checksum for all modules" - help - Modules which contain a MODULE_VERSION get an extra "srcversion" - field inserted into their modinfo section, which contains a - sum of the source files which made it. This helps maintainers - see exactly which source was used to build a module (since - others sometimes change the module source without updating - the version). With this option, such a "srcversion" field - will be created for all modules. If unsure, say N. - -config MODULE_SIG - bool "Module signature verification" - select MODULE_SIG_FORMAT - help - Check modules for valid signatures upon load: the signature - is simply appended to the module. For more information see - . - - Note that this option adds the OpenSSL development packages as a - kernel build dependency so that the signing tool can use its crypto - library. - - You should enable this option if you wish to use either - CONFIG_SECURITY_LOCKDOWN_LSM or lockdown functionality imposed via - another LSM - otherwise unsigned modules will be loadable regardless - of the lockdown policy. - - !!!WARNING!!! If you enable this option, you MUST make sure that the - module DOES NOT get stripped after being signed. This includes the - debuginfo strip done by some packagers (such as rpmbuild) and - inclusion into an initramfs that wants the module size reduced. - -config MODULE_SIG_FORCE - bool "Require modules to be validly signed" - depends on MODULE_SIG - help - Reject unsigned modules or signed modules for which we don't have a - key. Without this, such modules will simply taint the kernel. - -config MODULE_SIG_ALL - bool "Automatically sign all modules" - default y - depends on MODULE_SIG || IMA_APPRAISE_MODSIG - help - Sign all modules during make modules_install. Without this option, - modules must be signed manually, using the scripts/sign-file tool. - -comment "Do not forget to sign required modules with scripts/sign-file" - depends on MODULE_SIG_FORCE && !MODULE_SIG_ALL - -choice - prompt "Which hash algorithm should modules be signed with?" - depends on MODULE_SIG || IMA_APPRAISE_MODSIG - help - This determines which sort of hashing algorithm will be used during - signature generation. This algorithm _must_ be built into the kernel - directly so that signature verification can take place. It is not - possible to load a signed module containing the algorithm to check - the signature on that module. - -config MODULE_SIG_SHA1 - bool "Sign modules with SHA-1" - select CRYPTO_SHA1 - -config MODULE_SIG_SHA224 - bool "Sign modules with SHA-224" - select CRYPTO_SHA256 - -config MODULE_SIG_SHA256 - bool "Sign modules with SHA-256" - select CRYPTO_SHA256 - -config MODULE_SIG_SHA384 - bool "Sign modules with SHA-384" - select CRYPTO_SHA512 - -config MODULE_SIG_SHA512 - bool "Sign modules with SHA-512" - select CRYPTO_SHA512 - -endchoice - -config MODULE_SIG_HASH - string - depends on MODULE_SIG || IMA_APPRAISE_MODSIG - default "sha1" if MODULE_SIG_SHA1 - default "sha224" if MODULE_SIG_SHA224 - default "sha256" if MODULE_SIG_SHA256 - default "sha384" if MODULE_SIG_SHA384 - default "sha512" if MODULE_SIG_SHA512 - -choice - prompt "Module compression mode" - help - This option allows you to choose the algorithm which will be used to - compress modules when 'make modules_install' is run. (or, you can - choose to not compress modules at all.) - - External modules will also be compressed in the same way during the - installation. - - For modules inside an initrd or initramfs, it's more efficient to - compress the whole initrd or initramfs instead. - - This is fully compatible with signed modules. - - Please note that the tool used to load modules needs to support the - corresponding algorithm. module-init-tools MAY support gzip, and kmod - MAY support gzip, xz and zstd. - - Your build system needs to provide the appropriate compression tool - to compress the modules. - - If in doubt, select 'None'. - -config MODULE_COMPRESS_NONE - bool "None" - help - Do not compress modules. The installed modules are suffixed - with .ko. - -config MODULE_COMPRESS_GZIP - bool "GZIP" - help - Compress modules with GZIP. The installed modules are suffixed - with .ko.gz. - -config MODULE_COMPRESS_XZ - bool "XZ" - help - Compress modules with XZ. The installed modules are suffixed - with .ko.xz. - -config MODULE_COMPRESS_ZSTD - bool "ZSTD" - help - Compress modules with ZSTD. The installed modules are suffixed - with .ko.zst. - -endchoice - -config MODULE_DECOMPRESS - bool "Support in-kernel module decompression" - depends on MODULE_COMPRESS_GZIP || MODULE_COMPRESS_XZ - select ZLIB_INFLATE if MODULE_COMPRESS_GZIP - select XZ_DEC if MODULE_COMPRESS_XZ - help - - Support for decompressing kernel modules by the kernel itself - instead of relying on userspace to perform this task. Useful when - load pinning security policy is enabled. - - If unsure, say N. - -config MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS - bool "Allow loading of modules with missing namespace imports" - help - Symbols exported with EXPORT_SYMBOL_NS*() are considered exported in - a namespace. A module that makes use of a symbol exported with such a - namespace is required to import the namespace via MODULE_IMPORT_NS(). - There is no technical reason to enforce correct namespace imports, - but it creates consistency between symbols defining namespaces and - users importing namespaces they make use of. This option relaxes this - requirement and lifts the enforcement when loading a module. - - If unsure, say N. - -config MODPROBE_PATH - string "Path to modprobe binary" - default "/sbin/modprobe" - help - When kernel code requests a module, it does so by calling - the "modprobe" userspace utility. This option allows you to - set the path where that binary is found. This can be changed - at runtime via the sysctl file - /proc/sys/kernel/modprobe. Setting this to the empty string - removes the kernel's ability to request modules (but - userspace can still load modules explicitly). - -config TRIM_UNUSED_KSYMS - bool "Trim unused exported kernel symbols" if EXPERT - depends on !COMPILE_TEST - help - The kernel and some modules make many symbols available for - other modules to use via EXPORT_SYMBOL() and variants. Depending - on the set of modules being selected in your kernel configuration, - many of those exported symbols might never be used. - - This option allows for unused exported symbols to be dropped from - the build. In turn, this provides the compiler more opportunities - (especially when using LTO) for optimizing the code and reducing - binary size. This might have some security advantages as well. - - If unsure, or if you need to build out-of-tree modules, say N. - -config UNUSED_KSYMS_WHITELIST - string "Whitelist of symbols to keep in ksymtab" - depends on TRIM_UNUSED_KSYMS - help - By default, all unused exported symbols will be un-exported from the - build when TRIM_UNUSED_KSYMS is selected. - - UNUSED_KSYMS_WHITELIST allows to whitelist symbols that must be kept - exported at all times, even in absence of in-tree users. The value to - set here is the path to a text file containing the list of symbols, - one per line. The path can be absolute, or relative to the kernel - source tree. - -endif # MODULES - -config MODULES_TREE_LOOKUP - def_bool y - depends on PERF_EVENTS || TRACING || CFI_CLANG +source "kernel/module/Kconfig" config INIT_ALL_POSSIBLE bool diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig new file mode 100644 index 000000000000..9177cb38ea2e --- /dev/null +++ b/kernel/module/Kconfig @@ -0,0 +1,286 @@ +# SPDX-License-Identifier: GPL-2.0-only +menuconfig MODULES + bool "Enable loadable module support" + modules + help + Kernel modules are small pieces of compiled code which can + be inserted in the running kernel, rather than being + permanently built into the kernel. You use the "modprobe" + tool to add (and sometimes remove) them. If you say Y here, + many parts of the kernel can be built as modules (by + answering M instead of Y where indicated): this is most + useful for infrequently used options which are not required + for booting. For more information, see the man pages for + modprobe, lsmod, modinfo, insmod and rmmod. + + If you say Y here, you will need to run "make + modules_install" to put the modules under /lib/modules/ + where modprobe can find them (you may need to be root to do + this). + + If unsure, say Y. + +if MODULES + +config MODULE_FORCE_LOAD + bool "Forced module loading" + default n + help + Allow loading of modules without version information (ie. modprobe + --force). Forced module loading sets the 'F' (forced) taint flag and + is usually a really bad idea. + +config MODULE_UNLOAD + bool "Module unloading" + help + Without this option you will not be able to unload any + modules (note that some modules may not be unloadable + anyway), which makes your kernel smaller, faster + and simpler. If unsure, say Y. + +config MODULE_FORCE_UNLOAD + bool "Forced module unloading" + depends on MODULE_UNLOAD + help + This option allows you to force a module to unload, even if the + kernel believes it is unsafe: the kernel will remove the module + without waiting for anyone to stop using it (using the -f option to + rmmod). This is mainly for kernel developers and desperate users. + If unsure, say N. + +config MODVERSIONS + bool "Module versioning support" + help + Usually, you have to use modules compiled with your kernel. + Saying Y here makes it sometimes possible to use modules + compiled for different kernels, by adding enough information + to the modules to (hopefully) spot any changes which would + make them incompatible with the kernel you are running. If + unsure, say N. + +config ASM_MODVERSIONS + bool + default HAVE_ASM_MODVERSIONS && MODVERSIONS + help + This enables module versioning for exported symbols also from + assembly. This can be enabled only when the target architecture + supports it. + +config MODULE_REL_CRCS + bool + depends on MODVERSIONS + +config MODULE_SRCVERSION_ALL + bool "Source checksum for all modules" + help + Modules which contain a MODULE_VERSION get an extra "srcversion" + field inserted into their modinfo section, which contains a + sum of the source files which made it. This helps maintainers + see exactly which source was used to build a module (since + others sometimes change the module source without updating + the version). With this option, such a "srcversion" field + will be created for all modules. If unsure, say N. + +config MODULE_SIG + bool "Module signature verification" + select MODULE_SIG_FORMAT + help + Check modules for valid signatures upon load: the signature + is simply appended to the module. For more information see + . + + Note that this option adds the OpenSSL development packages as a + kernel build dependency so that the signing tool can use its crypto + library. + + You should enable this option if you wish to use either + CONFIG_SECURITY_LOCKDOWN_LSM or lockdown functionality imposed via + another LSM - otherwise unsigned modules will be loadable regardless + of the lockdown policy. + + !!!WARNING!!! If you enable this option, you MUST make sure that the + module DOES NOT get stripped after being signed. This includes the + debuginfo strip done by some packagers (such as rpmbuild) and + inclusion into an initramfs that wants the module size reduced. + +config MODULE_SIG_FORCE + bool "Require modules to be validly signed" + depends on MODULE_SIG + help + Reject unsigned modules or signed modules for which we don't have a + key. Without this, such modules will simply taint the kernel. + +config MODULE_SIG_ALL + bool "Automatically sign all modules" + default y + depends on MODULE_SIG || IMA_APPRAISE_MODSIG + help + Sign all modules during make modules_install. Without this option, + modules must be signed manually, using the scripts/sign-file tool. + +comment "Do not forget to sign required modules with scripts/sign-file" + depends on MODULE_SIG_FORCE && !MODULE_SIG_ALL + +choice + prompt "Which hash algorithm should modules be signed with?" + depends on MODULE_SIG || IMA_APPRAISE_MODSIG + help + This determines which sort of hashing algorithm will be used during + signature generation. This algorithm _must_ be built into the kernel + directly so that signature verification can take place. It is not + possible to load a signed module containing the algorithm to check + the signature on that module. + +config MODULE_SIG_SHA1 + bool "Sign modules with SHA-1" + select CRYPTO_SHA1 + +config MODULE_SIG_SHA224 + bool "Sign modules with SHA-224" + select CRYPTO_SHA256 + +config MODULE_SIG_SHA256 + bool "Sign modules with SHA-256" + select CRYPTO_SHA256 + +config MODULE_SIG_SHA384 + bool "Sign modules with SHA-384" + select CRYPTO_SHA512 + +config MODULE_SIG_SHA512 + bool "Sign modules with SHA-512" + select CRYPTO_SHA512 + +endchoice + +config MODULE_SIG_HASH + string + depends on MODULE_SIG || IMA_APPRAISE_MODSIG + default "sha1" if MODULE_SIG_SHA1 + default "sha224" if MODULE_SIG_SHA224 + default "sha256" if MODULE_SIG_SHA256 + default "sha384" if MODULE_SIG_SHA384 + default "sha512" if MODULE_SIG_SHA512 + +choice + prompt "Module compression mode" + help + This option allows you to choose the algorithm which will be used to + compress modules when 'make modules_install' is run. (or, you can + choose to not compress modules at all.) + + External modules will also be compressed in the same way during the + installation. + + For modules inside an initrd or initramfs, it's more efficient to + compress the whole initrd or initramfs instead. + + This is fully compatible with signed modules. + + Please note that the tool used to load modules needs to support the + corresponding algorithm. module-init-tools MAY support gzip, and kmod + MAY support gzip, xz and zstd. + + Your build system needs to provide the appropriate compression tool + to compress the modules. + + If in doubt, select 'None'. + +config MODULE_COMPRESS_NONE + bool "None" + help + Do not compress modules. The installed modules are suffixed + with .ko. + +config MODULE_COMPRESS_GZIP + bool "GZIP" + help + Compress modules with GZIP. The installed modules are suffixed + with .ko.gz. + +config MODULE_COMPRESS_XZ + bool "XZ" + help + Compress modules with XZ. The installed modules are suffixed + with .ko.xz. + +config MODULE_COMPRESS_ZSTD + bool "ZSTD" + help + Compress modules with ZSTD. The installed modules are suffixed + with .ko.zst. + +endchoice + +config MODULE_DECOMPRESS + bool "Support in-kernel module decompression" + depends on MODULE_COMPRESS_GZIP || MODULE_COMPRESS_XZ + select ZLIB_INFLATE if MODULE_COMPRESS_GZIP + select XZ_DEC if MODULE_COMPRESS_XZ + help + + Support for decompressing kernel modules by the kernel itself + instead of relying on userspace to perform this task. Useful when + load pinning security policy is enabled. + + If unsure, say N. + +config MODULE_ALLOW_MISSING_NAMESPACE_IMPORTS + bool "Allow loading of modules with missing namespace imports" + help + Symbols exported with EXPORT_SYMBOL_NS*() are considered exported in + a namespace. A module that makes use of a symbol exported with such a + namespace is required to import the namespace via MODULE_IMPORT_NS(). + There is no technical reason to enforce correct namespace imports, + but it creates consistency between symbols defining namespaces and + users importing namespaces they make use of. This option relaxes this + requirement and lifts the enforcement when loading a module. + + If unsure, say N. + +config MODPROBE_PATH + string "Path to modprobe binary" + default "/sbin/modprobe" + help + When kernel code requests a module, it does so by calling + the "modprobe" userspace utility. This option allows you to + set the path where that binary is found. This can be changed + at runtime via the sysctl file + /proc/sys/kernel/modprobe. Setting this to the empty string + removes the kernel's ability to request modules (but + userspace can still load modules explicitly). + +config TRIM_UNUSED_KSYMS + bool "Trim unused exported kernel symbols" if EXPERT + depends on !COMPILE_TEST + help + The kernel and some modules make many symbols available for + other modules to use via EXPORT_SYMBOL() and variants. Depending + on the set of modules being selected in your kernel configuration, + many of those exported symbols might never be used. + + This option allows for unused exported symbols to be dropped from + the build. In turn, this provides the compiler more opportunities + (especially when using LTO) for optimizing the code and reducing + binary size. This might have some security advantages as well. + + If unsure, or if you need to build out-of-tree modules, say N. + +config UNUSED_KSYMS_WHITELIST + string "Whitelist of symbols to keep in ksymtab" + depends on TRIM_UNUSED_KSYMS + help + By default, all unused exported symbols will be un-exported from the + build when TRIM_UNUSED_KSYMS is selected. + + UNUSED_KSYMS_WHITELIST allows to whitelist symbols that must be kept + exported at all times, even in absence of in-tree users. The value to + set here is the path to a text file containing the list of symbols, + one per line. The path can be absolute, or relative to the kernel + source tree. + +config MODULES_TREE_LOOKUP + def_bool y + depends on PERF_EVENTS || TRACING || CFI_CLANG + +endif # MODULES From patchwork Tue Feb 22 10:38:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Leroy X-Patchwork-Id: 12754861 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C446FC433EF for ; Tue, 22 Feb 2022 10:39:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231374AbiBVKkC (ORCPT ); Tue, 22 Feb 2022 05:40:02 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45264 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231345AbiBVKkB (ORCPT ); Tue, 22 Feb 2022 05:40:01 -0500 Received: from pegase2.c-s.fr (pegase2.c-s.fr [93.17.235.10]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B2BDE15AF0B; Tue, 22 Feb 2022 02:39:28 -0800 (PST) Received: from localhost (mailhub3.si.c-s.fr [172.26.127.67]) by localhost (Postfix) with ESMTP id 4K2wdg3fXjz9sT3; Tue, 22 Feb 2022 11:39:19 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase2.c-s.fr ([172.26.127.65]) by localhost (pegase2.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id GRVDt1ma9003; Tue, 22 Feb 2022 11:39:19 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase2.c-s.fr (Postfix) with ESMTP id 4K2wdb6n0nz9sT6; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id D42808B775; Tue, 22 Feb 2022 11:39:15 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id 2JQS3JBMQiUq; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from PO20335.IDSI0.si.c-s.fr (unknown [172.25.230.108]) by messagerie.si.c-s.fr (Postfix) with ESMTP id A65618B77B; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 21MAd7601076214 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 22 Feb 2022 11:39:07 +0100 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 21MAd7G41076213; Tue, 22 Feb 2022 11:39:07 +0100 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Aaron Tomlin , Luis Chamberlain , linux-modules@vger.kernel.org Cc: Christophe Leroy , linux-kernel@vger.kernel.org Subject: [PATCH v1 3/6] module: Make module_enable_x() independent of CONFIG_ARCH_HAS_STRICT_MODULE_RWX Date: Tue, 22 Feb 2022 11:38:57 +0100 Message-Id: <833727c3ed2e66c9b160ccfcc9d2b452da92ca23.1645526008.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1645526317; l=3337; s=20211009; h=from:subject:message-id; bh=RG6DR47DOXQKCABFO0zK5+DonamOgpblUuRXExx+I1U=; b=kam9oZ870YOWjIdezshJ6cY+AhYQa/tWIE3leswUsQM+ui5sTMU/FZ89F6EWgY/dxZ/dD0rhu0Bs x7wSyPzPAYwVyYnyA/3U4JiiREO/wzLtbpqyGT/y+XS1AmoRW+ye X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Precedence: bulk List-ID: module_enable_x() has nothing to do with CONFIG_ARCH_HAS_STRICT_MODULE_RWX allthough by coincidence architectures who need module_enable_x() are selection CONFIG_ARCH_HAS_STRICT_MODULE_RWX. Enable module_enable_x() for everyone everytime. If an architecture already has module text set executable, it's a no-op. Don't check text_size alignment. When CONFIG_STRICT_MODULE_RWX is set the verification is already done in frob_rodata(). When CONFIG_STRICT_MODULE_RWX is not set it is not a big deal to have the start of data as executable. Just make sure we entirely get the last page when the boundary is not aligned. And don't BUG on misaligned base as some architectures like nios2 use kmalloc() for allocating modules. So just bail out in that case. If that's a problem, a page fault will occur later anyway. Signed-off-by: Christophe Leroy --- kernel/module/internal.h | 6 ++---- kernel/module/main.c | 13 ++++++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/kernel/module/internal.h b/kernel/module/internal.h index 27ea99707059..ec4b46c67d10 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -27,9 +27,9 @@ /* * Modules' sections will be aligned on page boundaries * to ensure complete separation of code and data, but - * only when CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y + * only when CONFIG_STRICT_MODULE_RWX=y */ -#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX +#ifdef CONFIG_STRICT_MODULE_RWX # define debug_align(X) PAGE_ALIGN(X) #else # define debug_align(X) (X) @@ -182,10 +182,8 @@ static inline struct module *mod_find(unsigned long addr, struct mod_tree_root * } #endif /* CONFIG_MODULES_TREE_LOOKUP */ -#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX void frob_text(const struct module_layout *layout, int (*set_memory)(unsigned long start, int num_pages)); -#endif /* CONFIG_ARCH_HAS_STRICT_MODULE_RWX */ #ifdef CONFIG_STRICT_MODULE_RWX void module_enable_ro(const struct module *mod, bool after_init); diff --git a/kernel/module/main.c b/kernel/module/main.c index db503a212532..2b2f5d79bd7a 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -1162,24 +1162,23 @@ resolve_symbol_wait(struct module *mod, * CONFIG_STRICT_MODULE_RWX block below because they are needed regardless of * whether we are strict. */ -#ifdef CONFIG_ARCH_HAS_STRICT_MODULE_RWX void frob_text(const struct module_layout *layout, int (*set_memory)(unsigned long start, int num_pages)) { - BUG_ON((unsigned long)layout->base & (PAGE_SIZE-1)); - BUG_ON((unsigned long)layout->text_size & (PAGE_SIZE-1)); set_memory((unsigned long)layout->base, - layout->text_size >> PAGE_SHIFT); + PAGE_ALIGN(layout->text_size) >> PAGE_SHIFT); } static void module_enable_x(const struct module *mod) { + if (!PAGE_ALIGNED(mod->core_layout.base)) + return; + if (!PAGE_ALIGNED(mod->init_layout.base)) + return; + frob_text(&mod->core_layout, set_memory_x); frob_text(&mod->init_layout, set_memory_x); } -#else /* !CONFIG_ARCH_HAS_STRICT_MODULE_RWX */ -static void module_enable_x(const struct module *mod) { } -#endif /* CONFIG_ARCH_HAS_STRICT_MODULE_RWX */ void __weak module_memfree(void *module_region) { From patchwork Tue Feb 22 10:38:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Leroy X-Patchwork-Id: 12754864 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id A597EC4332F for ; Tue, 22 Feb 2022 10:39:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231327AbiBVKkF (ORCPT ); Tue, 22 Feb 2022 05:40:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45280 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231358AbiBVKkB (ORCPT ); Tue, 22 Feb 2022 05:40:01 -0500 Received: from pegase2.c-s.fr (pegase2.c-s.fr [93.17.235.10]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ABC4915AF12; Tue, 22 Feb 2022 02:39:32 -0800 (PST) Received: from localhost (mailhub3.si.c-s.fr [172.26.127.67]) by localhost (Postfix) with ESMTP id 4K2wdh4K2tz9sT6; Tue, 22 Feb 2022 11:39:20 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase2.c-s.fr ([172.26.127.65]) by localhost (pegase2.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id h2jlBWO3szAD; Tue, 22 Feb 2022 11:39:20 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase2.c-s.fr (Postfix) with ESMTP id 4K2wdb6mYjz9sT5; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id D5DAD8B783; Tue, 22 Feb 2022 11:39:15 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id PlSJrMjOJ7r2; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from PO20335.IDSI0.si.c-s.fr (unknown [172.25.230.108]) by messagerie.si.c-s.fr (Postfix) with ESMTP id A46CA8B779; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 21MAd7Ra1076218 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 22 Feb 2022 11:39:07 +0100 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 21MAd7HK1076217; Tue, 22 Feb 2022 11:39:07 +0100 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Aaron Tomlin , Luis Chamberlain , linux-modules@vger.kernel.org Cc: Christophe Leroy , linux-kernel@vger.kernel.org Subject: [PATCH v1 4/6] module: Move module_enable_x() and frob_text() in strict_rwx.c Date: Tue, 22 Feb 2022 11:38:58 +0100 Message-Id: <8fdf932ba4ae4b6a72b7439dbe4fedb7de30ae3e.1645526008.git.christophe.leroy@csgroup.eu> X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1645526317; l=7350; s=20211009; h=from:subject:message-id; bh=DzolO/LhQKwrnqLza+xjE1AU+Gi9hEBK6ObvQJ8/Yrs=; b=JEcB6uyK8hDuEqB91pib7jW/KRXUWlpDFeKIcuq7uDq8aOUWaXYhWp/3xTj7aRf6qgtO5dR83feT B+iuLWuADEZscBso9a9NhiU+jVbU80GQiECeXOllWcGRxiIzLVWP X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Precedence: bulk List-ID: Move module_enable_x() together with module_enable_nx() and module_enable_ro(). Those three functions are going together, they are all used to set up the correct page flags on the different sections. As module_enable_x() is used independently of CONFIG_STRICT_MODULE_RWX, build strict_rwx.c all the time and use IS_ENABLED(CONFIG_STRICT_MODULE_RWX) when relevant. Signed-off-by: Christophe Leroy --- kernel/module/Makefile | 3 +-- kernel/module/internal.h | 15 +----------- kernel/module/main.c | 38 ------------------------------ kernel/module/strict_rwx.c | 48 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 54 deletions(-) diff --git a/kernel/module/Makefile b/kernel/module/Makefile index 5fe90d246fcc..037ecc72ac23 100644 --- a/kernel/module/Makefile +++ b/kernel/module/Makefile @@ -7,12 +7,11 @@ # and produce insane amounts of uninteresting coverage. KCOV_INSTRUMENT_main.o := n -obj-y += main.o +obj-y += main.o strict_rwx.o obj-$(CONFIG_MODULE_DECOMPRESS) += decompress.o obj-$(CONFIG_MODULE_SIG) += signing.o obj-$(CONFIG_LIVEPATCH) += livepatch.o obj-$(CONFIG_MODULES_TREE_LOOKUP) += tree_lookup.o -obj-$(CONFIG_STRICT_MODULE_RWX) += strict_rwx.o obj-$(CONFIG_DEBUG_KMEMLEAK) += debug_kmemleak.o obj-$(CONFIG_KALLSYMS) += kallsyms.o obj-$(CONFIG_PROC_FS) += procfs.o diff --git a/kernel/module/internal.h b/kernel/module/internal.h index ec4b46c67d10..b80a746b2e5a 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -182,25 +182,12 @@ static inline struct module *mod_find(unsigned long addr, struct mod_tree_root * } #endif /* CONFIG_MODULES_TREE_LOOKUP */ -void frob_text(const struct module_layout *layout, int (*set_memory)(unsigned long start, - int num_pages)); - -#ifdef CONFIG_STRICT_MODULE_RWX void module_enable_ro(const struct module *mod, bool after_init); void module_enable_nx(const struct module *mod); +void module_enable_x(const struct module *mod); int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, char *secstrings, struct module *mod); -#else /* !CONFIG_STRICT_MODULE_RWX */ -static inline void module_enable_nx(const struct module *mod) { } -static inline void module_enable_ro(const struct module *mod, bool after_init) {} -static inline int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, - char *secstrings, struct module *mod) -{ - return 0; -} -#endif /* CONFIG_STRICT_MODULE_RWX */ - #ifdef CONFIG_MODULE_SIG int module_sig_check(struct load_info *info, int flags); #else /* !CONFIG_MODULE_SIG */ diff --git a/kernel/module/main.c b/kernel/module/main.c index 2b2f5d79bd7a..47addf849ef7 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -1142,44 +1142,6 @@ resolve_symbol_wait(struct module *mod, return ksym; } -/* - * LKM RO/NX protection: protect module's text/ro-data - * from modification and any data from execution. - * - * General layout of module is: - * [text] [read-only-data] [ro-after-init] [writable data] - * text_size -----^ ^ ^ ^ - * ro_size ------------------------| | | - * ro_after_init_size -----------------------------| | - * size -----------------------------------------------------------| - * - * These values are always page-aligned (as is base) - */ - -/* - * Since some arches are moving towards PAGE_KERNEL module allocations instead - * of PAGE_KERNEL_EXEC, keep frob_text() and module_enable_x() outside of the - * CONFIG_STRICT_MODULE_RWX block below because they are needed regardless of - * whether we are strict. - */ -void frob_text(const struct module_layout *layout, - int (*set_memory)(unsigned long start, int num_pages)) -{ - set_memory((unsigned long)layout->base, - PAGE_ALIGN(layout->text_size) >> PAGE_SHIFT); -} - -static void module_enable_x(const struct module *mod) -{ - if (!PAGE_ALIGNED(mod->core_layout.base)) - return; - if (!PAGE_ALIGNED(mod->init_layout.base)) - return; - - frob_text(&mod->core_layout, set_memory_x); - frob_text(&mod->init_layout, set_memory_x); -} - void __weak module_memfree(void *module_region) { /* diff --git a/kernel/module/strict_rwx.c b/kernel/module/strict_rwx.c index a2104e9233a5..b023cea06af0 100644 --- a/kernel/module/strict_rwx.c +++ b/kernel/module/strict_rwx.c @@ -11,6 +11,34 @@ #include #include "internal.h" +/* + * LKM RO/NX protection: protect module's text/ro-data + * from modification and any data from execution. + * + * General layout of module is: + * [text] [read-only-data] [ro-after-init] [writable data] + * text_size -----^ ^ ^ ^ + * ro_size ------------------------| | | + * ro_after_init_size -----------------------------| | + * size -----------------------------------------------------------| + * + * These values are always page-aligned (as is base) when + * CONFIG_STRICT_MODULE_RWX is set. + */ + +/* + * Since some arches are moving towards PAGE_KERNEL module allocations instead + * of PAGE_KERNEL_EXEC, keep frob_text() and module_enable_x() independent of + * CONFIG_STRICT_MODULE_RWX because they are needed regardless of whether we + * are strict. + */ +static void frob_text(const struct module_layout *layout, + int (*set_memory)(unsigned long start, int num_pages)) +{ + set_memory((unsigned long)layout->base, + PAGE_ALIGN(layout->text_size) >> PAGE_SHIFT); +} + static void frob_rodata(const struct module_layout *layout, int (*set_memory)(unsigned long start, int num_pages)) { @@ -41,10 +69,24 @@ static void frob_writable_data(const struct module_layout *layout, (layout->size - layout->ro_after_init_size) >> PAGE_SHIFT); } +void module_enable_x(const struct module *mod) +{ + if (!PAGE_ALIGNED(mod->core_layout.base) || + !PAGE_ALIGNED(mod->init_layout.base)) + return; + + frob_text(&mod->core_layout, set_memory_x); + frob_text(&mod->init_layout, set_memory_x); +} + void module_enable_ro(const struct module *mod, bool after_init) { + if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) + return; +#ifdef CONFIG_STRICT_MODULE_RWX if (!rodata_enabled) return; +#endif set_vm_flush_reset_perms(mod->core_layout.base); set_vm_flush_reset_perms(mod->init_layout.base); @@ -60,6 +102,9 @@ void module_enable_ro(const struct module *mod, bool after_init) void module_enable_nx(const struct module *mod) { + if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) + return; + frob_rodata(&mod->data_layout, set_memory_nx); frob_ro_after_init(&mod->data_layout, set_memory_nx); frob_writable_data(&mod->data_layout, set_memory_nx); @@ -73,6 +118,9 @@ int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, const unsigned long shf_wx = SHF_WRITE | SHF_EXECINSTR; int i; + if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) + return 0; + for (i = 0; i < hdr->e_shnum; i++) { if ((sechdrs[i].sh_flags & shf_wx) == shf_wx) { pr_err("%s: section %s (index %d) has invalid WRITE|EXEC flags\n", From patchwork Tue Feb 22 10:38:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Leroy X-Patchwork-Id: 12754859 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3B11EC433F5 for ; Tue, 22 Feb 2022 10:39:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231314AbiBVKjs (ORCPT ); Tue, 22 Feb 2022 05:39:48 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44764 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231310AbiBVKjp (ORCPT ); Tue, 22 Feb 2022 05:39:45 -0500 Received: from pegase2.c-s.fr (pegase2.c-s.fr [93.17.235.10]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BFFE51520E9; Tue, 22 Feb 2022 02:39:20 -0800 (PST) Received: from localhost (mailhub3.si.c-s.fr [172.26.127.67]) by localhost (Postfix) with ESMTP id 4K2wdd1GRcz9sT4; Tue, 22 Feb 2022 11:39:17 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase2.c-s.fr ([172.26.127.65]) by localhost (pegase2.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id zEPSRavfLS7v; Tue, 22 Feb 2022 11:39:17 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase2.c-s.fr (Postfix) with ESMTP id 4K2wdb6mXrz9sT2; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id D3E178B764; Tue, 22 Feb 2022 11:39:15 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id 66W3h899ZoQ9; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from PO20335.IDSI0.si.c-s.fr (unknown [172.25.230.108]) by messagerie.si.c-s.fr (Postfix) with ESMTP id A573F8B77A; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 21MAd7pD1076222 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 22 Feb 2022 11:39:07 +0100 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 21MAd7B91076221; Tue, 22 Feb 2022 11:39:07 +0100 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Aaron Tomlin , Luis Chamberlain , linux-modules@vger.kernel.org Cc: Christophe Leroy , linux-kernel@vger.kernel.org Subject: [PATCH v1 5/6] module: Rework layout alignment to avoid BUG_ON()s Date: Tue, 22 Feb 2022 11:38:59 +0100 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1645526317; l=4076; s=20211009; h=from:subject:message-id; bh=CYUOt3ARLhIdcgn+cH3ZQO7m4/B5fdRfsQumL45ql/U=; b=H9lAZ2UAafA4WnlxO3PpmepqcWE/H+KiGkreefXl3K+25hBgbYivleAWwW1s/NzI1+F7KCmXhEDs SIs4Mtn+DZKkITli2SWxEItJqqLsZ4TxgEtPTulMFl0q1ngoZIw1 X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Precedence: bulk List-ID: Perform layout alignment verification up front and WARN_ON() and fail module loading instead of crashing the machine. Signed-off-by: Christophe Leroy --- kernel/module/internal.h | 1 + kernel/module/main.c | 5 +++++ kernel/module/strict_rwx.c | 28 +++++++++++++++++++--------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/kernel/module/internal.h b/kernel/module/internal.h index b80a746b2e5a..32add08e7895 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -187,6 +187,7 @@ void module_enable_nx(const struct module *mod); void module_enable_x(const struct module *mod); int module_enforce_rwx_sections(Elf_Ehdr *hdr, Elf_Shdr *sechdrs, char *secstrings, struct module *mod); +bool module_check_misalignment(const struct module *mod); #ifdef CONFIG_MODULE_SIG int module_sig_check(struct load_info *info, int flags); diff --git a/kernel/module/main.c b/kernel/module/main.c index 47addf849ef7..4876e2beb5b6 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -2596,6 +2596,9 @@ static int complete_formation(struct module *mod, struct load_info *info) /* This relies on module_mutex for list integrity. */ module_bug_finalize(info->hdr, info->sechdrs, mod); + if (module_check_misalignment(mod)) + goto out_misaligned; + module_enable_ro(mod, false); module_enable_nx(mod); module_enable_x(mod); @@ -2609,6 +2612,8 @@ static int complete_formation(struct module *mod, struct load_info *info) return 0; +out_misaligned: + err = -EINVAL; out: mutex_unlock(&module_mutex); return err; diff --git a/kernel/module/strict_rwx.c b/kernel/module/strict_rwx.c index b023cea06af0..3966198a4fc0 100644 --- a/kernel/module/strict_rwx.c +++ b/kernel/module/strict_rwx.c @@ -42,9 +42,6 @@ static void frob_text(const struct module_layout *layout, static void frob_rodata(const struct module_layout *layout, int (*set_memory)(unsigned long start, int num_pages)) { - BUG_ON(!PAGE_ALIGNED(layout->base)); - BUG_ON(!PAGE_ALIGNED(layout->text_size)); - BUG_ON(!PAGE_ALIGNED(layout->ro_size)); set_memory((unsigned long)layout->base + layout->text_size, (layout->ro_size - layout->text_size) >> PAGE_SHIFT); } @@ -52,9 +49,6 @@ static void frob_rodata(const struct module_layout *layout, static void frob_ro_after_init(const struct module_layout *layout, int (*set_memory)(unsigned long start, int num_pages)) { - BUG_ON(!PAGE_ALIGNED(layout->base)); - BUG_ON(!PAGE_ALIGNED(layout->ro_size)); - BUG_ON(!PAGE_ALIGNED(layout->ro_after_init_size)); set_memory((unsigned long)layout->base + layout->ro_size, (layout->ro_after_init_size - layout->ro_size) >> PAGE_SHIFT); } @@ -62,13 +56,29 @@ static void frob_ro_after_init(const struct module_layout *layout, static void frob_writable_data(const struct module_layout *layout, int (*set_memory)(unsigned long start, int num_pages)) { - BUG_ON(!PAGE_ALIGNED(layout->base)); - BUG_ON(!PAGE_ALIGNED(layout->ro_after_init_size)); - BUG_ON(!PAGE_ALIGNED(layout->size)); set_memory((unsigned long)layout->base + layout->ro_after_init_size, (layout->size - layout->ro_after_init_size) >> PAGE_SHIFT); } +static bool layout_check_misalignment(const struct module_layout *layout) +{ + return WARN_ON(!PAGE_ALIGNED(layout->base)) || + WARN_ON(!PAGE_ALIGNED(layout->text_size)) || + WARN_ON(!PAGE_ALIGNED(layout->ro_size)) || + WARN_ON(!PAGE_ALIGNED(layout->ro_after_init_size)) || + WARN_ON(!PAGE_ALIGNED(layout->size)); +} + +bool module_check_misalignment(const struct module *mod) +{ + if (!IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) + return false; + + return layout_check_misalignment(&mod->core_layout) || + layout_check_misalignment(&mod->data_layout) || + layout_check_misalignment(&mod->init_layout); +} + void module_enable_x(const struct module *mod) { if (!PAGE_ALIGNED(mod->core_layout.base) || From patchwork Tue Feb 22 10:39:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Leroy X-Patchwork-Id: 12754863 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id C70D7C433EF for ; Tue, 22 Feb 2022 10:39:42 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231272AbiBVKkG (ORCPT ); Tue, 22 Feb 2022 05:40:06 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45388 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231337AbiBVKkF (ORCPT ); Tue, 22 Feb 2022 05:40:05 -0500 Received: from pegase2.c-s.fr (pegase2.c-s.fr [93.17.235.10]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 74C4115AF07; Tue, 22 Feb 2022 02:39:40 -0800 (PST) Received: from localhost (mailhub3.si.c-s.fr [172.26.127.67]) by localhost (Postfix) with ESMTP id 4K2wdk73wSz9sT7; Tue, 22 Feb 2022 11:39:22 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from pegase2.c-s.fr ([172.26.127.65]) by localhost (pegase2.c-s.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 3VRYSKs3UUlZ; Tue, 22 Feb 2022 11:39:22 +0100 (CET) Received: from messagerie.si.c-s.fr (messagerie.si.c-s.fr [192.168.25.192]) by pegase2.c-s.fr (Postfix) with ESMTP id 4K2wdc05MSz9sT8; Tue, 22 Feb 2022 11:39:16 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by messagerie.si.c-s.fr (Postfix) with ESMTP id E754B8B778; Tue, 22 Feb 2022 11:39:15 +0100 (CET) X-Virus-Scanned: amavisd-new at c-s.fr Received: from messagerie.si.c-s.fr ([127.0.0.1]) by localhost (messagerie.si.c-s.fr [127.0.0.1]) (amavisd-new, port 10023) with ESMTP id pQyDMfN9EdHD; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from PO20335.IDSI0.si.c-s.fr (unknown [172.25.230.108]) by messagerie.si.c-s.fr (Postfix) with ESMTP id A462B8B776; Tue, 22 Feb 2022 11:39:15 +0100 (CET) Received: from PO20335.IDSI0.si.c-s.fr (localhost [127.0.0.1]) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.16.1) with ESMTPS id 21MAd7Sc1076226 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Tue, 22 Feb 2022 11:39:07 +0100 Received: (from chleroy@localhost) by PO20335.IDSI0.si.c-s.fr (8.17.1/8.17.1/Submit) id 21MAd7TE1076225; Tue, 22 Feb 2022 11:39:07 +0100 X-Authentication-Warning: PO20335.IDSI0.si.c-s.fr: chleroy set sender to christophe.leroy@csgroup.eu using -f From: Christophe Leroy To: Aaron Tomlin , Luis Chamberlain , linux-modules@vger.kernel.org Cc: Christophe Leroy , linux-kernel@vger.kernel.org Subject: [PATCH v1 6/6] module: Rename debug_align() as strict_align() Date: Tue, 22 Feb 2022 11:39:00 +0100 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: MIME-Version: 1.0 X-Developer-Signature: v=1; a=ed25519-sha256; t=1645526317; l=4185; s=20211009; h=from:subject:message-id; bh=0qZWa23U1bz9DrTNyd0D7ysxbN+QdZvyKcOSMofY7EE=; b=9+JhamhOvNqqAcKvvuoYpzDhKjAsjo8lr6WfQqxyUPitOQZW3TIafhrbz5IV4SVFgEJKGG8L/d3Z 2Qf+URrRAoc+Ze0F23mCcygJFGVhtf/wtmcc08cdIsjefEnrkbEJ X-Developer-Key: i=christophe.leroy@csgroup.eu; a=ed25519; pk=HIzTzUj91asvincQGOFx6+ZF5AoUuP9GdOtQChs7Mm0= Precedence: bulk List-ID: debug_align() was added by commit 84e1c6bb38eb ("x86: Add RO/NX protection for loadable kernel modules") At that time the config item was CONFIG_DEBUG_SET_MODULE_RONX. But nowadays it has changed to CONFIG_STRICT_MODULE_RWX and debug_align() is confusing because it has nothing to do with DEBUG. Rename it strict_align() Signed-off-by: Christophe Leroy --- kernel/module/internal.h | 4 ++-- kernel/module/kallsyms.c | 4 ++-- kernel/module/main.c | 14 +++++++------- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/kernel/module/internal.h b/kernel/module/internal.h index 32add08e7895..c66f9da3e03d 100644 --- a/kernel/module/internal.h +++ b/kernel/module/internal.h @@ -30,9 +30,9 @@ * only when CONFIG_STRICT_MODULE_RWX=y */ #ifdef CONFIG_STRICT_MODULE_RWX -# define debug_align(X) PAGE_ALIGN(X) +# define strict_align(X) PAGE_ALIGN(X) #else -# define debug_align(X) (X) +# define strict_align(X) (X) #endif extern struct mutex module_mutex; diff --git a/kernel/module/kallsyms.c b/kernel/module/kallsyms.c index fe6723c040be..523a6ed8886b 100644 --- a/kernel/module/kallsyms.c +++ b/kernel/module/kallsyms.c @@ -139,7 +139,7 @@ void layout_symtab(struct module *mod, struct load_info *info) mod->data_layout.size += strtab_size; info->core_typeoffs = mod->data_layout.size; mod->data_layout.size += ndst * sizeof(char); - mod->data_layout.size = debug_align(mod->data_layout.size); + mod->data_layout.size = strict_align(mod->data_layout.size); /* Put string table section at end of init part of module. */ strsect->sh_flags |= SHF_ALLOC; @@ -154,7 +154,7 @@ void layout_symtab(struct module *mod, struct load_info *info) mod->init_layout.size += sizeof(struct mod_kallsyms); info->init_typeoffs = mod->init_layout.size; mod->init_layout.size += nsrc * sizeof(char); - mod->init_layout.size = debug_align(mod->init_layout.size); + mod->init_layout.size = strict_align(mod->init_layout.size); } /* diff --git a/kernel/module/main.c b/kernel/module/main.c index 4876e2beb5b6..ce0ef17662c9 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -1470,19 +1470,19 @@ static void layout_sections(struct module *mod, struct load_info *info) } switch (m) { case 0: /* executable */ - mod->core_layout.size = debug_align(mod->core_layout.size); + mod->core_layout.size = strict_align(mod->core_layout.size); mod->core_layout.text_size = mod->core_layout.size; break; case 1: /* RO: text and ro-data */ - mod->data_layout.size = debug_align(mod->data_layout.size); + mod->data_layout.size = strict_align(mod->data_layout.size); mod->data_layout.ro_size = mod->data_layout.size; break; case 2: /* RO after init */ - mod->data_layout.size = debug_align(mod->data_layout.size); + mod->data_layout.size = strict_align(mod->data_layout.size); mod->data_layout.ro_after_init_size = mod->data_layout.size; break; case 4: /* whole core */ - mod->data_layout.size = debug_align(mod->data_layout.size); + mod->data_layout.size = strict_align(mod->data_layout.size); break; } } @@ -1504,11 +1504,11 @@ static void layout_sections(struct module *mod, struct load_info *info) } switch (m) { case 0: /* executable */ - mod->init_layout.size = debug_align(mod->init_layout.size); + mod->init_layout.size = strict_align(mod->init_layout.size); mod->init_layout.text_size = mod->init_layout.size; break; case 1: /* RO: text and ro-data */ - mod->init_layout.size = debug_align(mod->init_layout.size); + mod->init_layout.size = strict_align(mod->init_layout.size); mod->init_layout.ro_size = mod->init_layout.size; break; case 2: @@ -1519,7 +1519,7 @@ static void layout_sections(struct module *mod, struct load_info *info) mod->init_layout.ro_after_init_size = mod->init_layout.ro_size; break; case 4: /* whole init */ - mod->init_layout.size = debug_align(mod->init_layout.size); + mod->init_layout.size = strict_align(mod->init_layout.size); break; } }