On Wed, Dec 25, 2024 at 11:52:00PM +0100, Thomas Weißschuh wrote: > diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig > index > 7b329057997ad2ec310133ca84617d9bfcdb7e9f..57d317a6fa444195d0806e6bd7a2af6e338a7f01 > 100644 > --- a/kernel/module/Kconfig > +++ b/kernel/module/Kconfig > @@ -344,6 +344,17 @@ config MODULE_DECOMPRESS > > If unsure, say N. > > +config MODULE_HASHES > + bool "Module hash validation" > + depends on !MODULE_SIG
Why are these mutually exclusive? Can't you want module signatures *and* this as well? What distro which is using module signatures would switch to this as an alternative instead? The help menu does not clarify any of this at all, and neither does the patch. > + select CRYPTO_LIB_SHA256 > + help > + Validate modules by their hashes. > + Only modules built together with the main kernel image can be > + validated that way. > + > + 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..6fe0c14ca5a05b49c1161fcfa8aaa130f89b70e1 > 100644 > --- a/kernel/module/Makefile > +++ b/kernel/module/Makefile > @@ -23,3 +23,4 @@ obj-$(CONFIG_KGDB_KDB) += kdb.o > obj-$(CONFIG_MODVERSIONS) += version.o > obj-$(CONFIG_MODULE_UNLOAD_TAINT_TRACKING) += tracking.o > obj-$(CONFIG_MODULE_STATS) += stats.o > +obj-$(CONFIG_MODULE_HASHES) += hashes.o > diff --git a/kernel/module/hashes.c b/kernel/module/hashes.c > new file mode 100644 > index > 0000000000000000000000000000000000000000..f19eccb0e3754e3edbf5cdea6d418da5c6ae6c65 > --- /dev/null > +++ b/kernel/module/hashes.c > @@ -0,0 +1,51 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > + > +#define pr_fmt(fmt) "module/hash: " fmt > + > +#include <linux/int_log.h> > +#include <linux/module_hashes.h> > +#include <linux/module.h> > +#include <crypto/sha2.h> > +#include "internal.h" > + > +static inline size_t module_hashes_count(void) > +{ > + return (__stop_module_hashes - __start_module_hashes) / > MODULE_HASHES_HASH_SIZE; > +} > + > +static __init __maybe_unused int module_hashes_init(void) > +{ > + size_t num_hashes = module_hashes_count(); > + int num_width = (intlog10(num_hashes) >> 24) + 1; > + size_t i; > + > + pr_debug("Builtin hashes (%zu):\n", num_hashes); > + > + for (i = 0; i < num_hashes; i++) > + pr_debug("%*zu %*phN\n", num_width, i, > + (int)sizeof(module_hashes[i]), module_hashes[i]); > + > + return 0; > +} > + > +#ifdef DEBUG We have MODULE_DEBUG so just add depend on that and leverage that for this instead. > diff --git a/scripts/module-hashes.sh b/scripts/module-hashes.sh > new file mode 100755 > index > 0000000000000000000000000000000000000000..7ca4e84f4c74266b9902d9f377aa2c901a06f995 > --- /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="${1:-}" > + > +echo "#include <linux/module_hashes.h>" > +echo > +echo "const u8 module_hashes[][MODULE_HASHES_HASH_SIZE] > __module_hashes_section = {" > + > +for mod in $(< modules.order); do > + mod="${mod/%.o/.ko}" > + if [ "$prealloc" = "prealloc" ]; then > + modhash="" > + else > + modhash="$(cksum -a sha256 --raw "$mod" | hexdump -v -e '"0x" > 1/1 "%02x, "')" > + fi > + echo " /* $mod */" > + echo " { $modhash }," > + echo > +done > + > +echo "};" Parallelize this. Luis