Hi guys, I normally hang out on irc on #gentoo-kernel and a bunch of other #gentoo-* channels. I stumble across the discussion of bug 447352 [1] that was reported by a user that was enforcing module signatures on the kernel. This made me to this patch (I talked to Mike before doing this).
Signed kernel modules require that the kernel is compiled with CONFIG_MODULE_SIG=y so that during compilation, the public key hash is stored in the kernel so that it can be verified later when insmod'ing an external module. There is no problem with in-tree modules, this are sign correctly and loaded, the problem is with out-of-the-tree modules installed by portage; this ones are not "signing ware". So this patch adds a new USE flag to the linux-mod.eclass named "module-signing". We enabled, it will check if the user has selected all the correct config options in the kernel, and optionally, where are the private and public parts of the key so that the module is signed and install time. If any of this fails, the installation of the module is aborted. >From the end user perspective, if he wants to add support for this, all he has to do is enable CONFIG_MODULE_SIG in the kernel. If no keys are found during the build, it will be generated one. If one wants to create a key himself, it's also possible to use this key, he just has to name it signing_key.priv and siging_key.x509 and put it under /usr/src/linux. After the kernel is compiled, this keys can be moved elsewhere and the path to them specified in make.conf under the vars KERNEL_MODSECKEY and KERNEL_MODPUBKEY. Patch below for review, discussion and testing. Thanks, Carlos Silva [1] https://bugs.gentoo.org/show_bug.cgi?id=447352 --- linux-mod.eclass 2012-09-15 16:31:15.000000000 +0000 +++ linux-mod.eclass 2013-03-06 15:57:25.808173694 -0100 @@ -125,9 +125,10 @@ inherit eutils linux-info multilib EXPORT_FUNCTIONS pkg_setup pkg_preinst pkg_postinst src_install src_compile pkg_postrm -IUSE="kernel_linux" +IUSE="module-signing kernel_linux" SLOT="0" -RDEPEND="kernel_linux? ( virtual/modutils )" +RDEPEND="kernel_linux? ( virtual/modutils ) + module-signing? ( dev-lang/perl dev-libs/openssl ) " DEPEND="${RDEPEND} sys-apps/sed kernel_linux? ( virtual/linux-sources )" @@ -208,6 +209,34 @@ fi } + +# internal function +# +# FUNCTION: check_module_signing +# DESCRIPTION: +# Checks for KERNEL_MODSECKEY, KERNEL_MODPUBKEY and verifies the files exists +check_module_signing() { + if ! use module-signing; then + return 1 + fi + + # Check that the configuration is correct + KERNEL_MODSECKEY="${KERNEL_MODSECKEY:-${KV_DIR}/signing_key.priv}" + KERNEL_MODPUBKEY="${KERNEL_MODPUBKEY:-${KV_DIR}/signing_key.x509}" + if [ ! -z "${KERNEL_MODSECKEY}x" -a ! -e "${KERNEL_MODSECKEY}" ]; then + eerror "KERNEL_MODSECKEY points to a missing file:" + eerror "${KERNEL_MODSECKEY}" + die "Invalid KERNEL_MODSECKEY" + fi + if [ ! -z "${KERNEL_MODPUBKEY}x" -a ! -e "${KERNEL_MODPUBKEY}" ]; then + eerror "KERNEL_MODPUBKEY points to a missing file." + eerror "${KERNEL_MODPUBKEY}" + die "Invalid KERNEL_MODPUBKEY" + fi + + return 0 +} + # internal function # # FUNCTION: update_depmod @@ -581,6 +610,10 @@ return fi + if use module-signing; then + CONFIG_CHECK+="${CONFIG_CHECK} MODULE_SIG" + fi + linux-info_pkg_setup; require_configured_kernel check_kernel_built; @@ -663,7 +696,7 @@ # This looks messy, but it is needed to handle multiple variables # being passed in the BUILD_* stuff where the variables also have - # spaces that must be preserved. If don't do this, then the stuff + # spaces that must be preserved. If dont do this, then the stuff # inside the variables gets used as targets for Make, which then # fails. eval "emake HOSTCC=\"$(tc-getBUILD_CC)\" \ @@ -710,6 +743,12 @@ srcdir=${srcdir:-${S}} objdir=${objdir:-${srcdir}} + if check_module_signing; then + ebegin "Signing module ${modulename}" + ${KV_DIR}/scripts/sign-file "${KERNEL_MODSECKEY}" "${KERNEL_MODPUBKEY}" "${objdir}/${modulename}.${KV_OBJ}" + eend $? + fi + einfo "Installing ${modulename} module" cd "${objdir}" || die "${objdir} does not exist" insinto /lib/modules/${KV_FULL}/${libdir}
