Hi,

There is an old bug[1] to support
linux kernel module signing at install.

And here is my first attempt to modify an eclass.
Need proper input on it and a kick in the right direction.

Add 3 variables, settable by users if they keep keys somewhere safe.
Otherwise it just works with the auto-generated keys 
if CONFIG_MODULE_SIG=y and vars are unset.

eclass will die if kernel requires a signed module,
but signing is not requested.


Known problems:

Packages that do not use linux-mod_src_install() will not sign 
the modules, 
But those packages will still inherit module-sign useflag.
It's misleading and I'm not sure how to fix that.
Examples : sys-kernel/spl, sys-fs/zfs-kmod

May need additional handling of KBUILD_SIGN_PIN variable[2],
which can be set to hold the passphrase to the key. But it may end up
in vdb environment files, not sure how to handle that or if it worth it

not eapi-7 ready because of STRIP_MASK usage.
will need to cover this case as well, probably later.

older (<4.3.3) kernels use perl to sign modules, not sure if it's worth
supporting old kernels, there is no gentoo-sources in the tree old
enough, except masked 4.1
there are old vanilla-sources that will be affected by this.


[1] https://bugs.gentoo.org/447352
[2] https://www.kernel.org/doc/html/v4.16/admin-guide/module-signing.html

diff --git a/eclass/linux-mod.eclass b/eclass/linux-mod.eclass
index bf580cf4cfa9..211b0496f528 100644
--- a/eclass/linux-mod.eclass
+++ b/eclass/linux-mod.eclass
@@ -14,7 +14,7 @@
 # required to install external modules against a kernel source
 # tree.
 
-# A Couple of env vars are available to effect usage of this eclass
+# Several env vars are available to effect usage of this eclass
 # These are as follows:
 
 # @ECLASS-VARIABLE: MODULES_OPTIONAL_USE
@@ -132,6 +132,31 @@
 # @DESCRIPTION:
 # It's a read-only variable. It contains the extension of the kernel modules.
 
+# @ECLASS-VARIABLE: KERNEL_MODULE_SIG_HASH
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# A string to control signing algorithm
+# Possible values: sha1:sha224:sha256:sha384:sha512
+# Defaults to value extracted from .config
+# Can be set by user in make.conf, as it can differ from kernel's.
+# In case of overriding this it's users responsibility to make sure
+# that kernel supports desired hash algo
+
+# @ECLASS-VARIABLE: KERNEL_MODULE_SIG_PEM
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# A string, containing path to the private key filename or PKCS#11 URI
+# Defaults to ${KV_DIR}/certs/signing_key.pem} if unset.
+# Can be set by user in make.conf
+
+# @ECLASS-VARIABLE: KERNEL_MODULE_SIG_X509
+# @DEFAULT_UNSET
+# @DESCRIPTION:
+# A string, containing path to the public key filename
+# Defaults to ${KV_DIR}/certs/signing_key.x509} if unset.
+# Can be set by user in make.conf
+
+
 inherit eutils linux-info multilib
 EXPORT_FUNCTIONS pkg_setup pkg_preinst pkg_postinst src_install src_compile 
pkg_postrm
 
@@ -144,12 +169,13 @@ esac
        0) die "EAPI=${EAPI} is not supported with 
MODULES_OPTIONAL_USE_IUSE_DEFAULT due to lack of IUSE defaults" ;;
 esac
 
-IUSE="kernel_linux 
${MODULES_OPTIONAL_USE:+${_modules_optional_use_iuse_default}}${MODULES_OPTIONAL_USE}"
+IUSE="module-sign kernel_linux 
${MODULES_OPTIONAL_USE:+${_modules_optional_use_iuse_default}}${MODULES_OPTIONAL_USE}"
 SLOT="0"
 RDEPEND="${MODULES_OPTIONAL_USE}${MODULES_OPTIONAL_USE:+? (} kernel_linux? ( 
virtual/modutils ) ${MODULES_OPTIONAL_USE:+)}"
 DEPEND="${RDEPEND}
     ${MODULES_OPTIONAL_USE}${MODULES_OPTIONAL_USE:+? (}
        sys-apps/sed
+       module-sign? ( || ( dev-libs/openssl dev-libs/libressl ) )
        kernel_linux? ( virtual/linux-sources )
        ${MODULES_OPTIONAL_USE:+)}"
 
@@ -196,6 +222,25 @@ check_vermagic() {
        fi
 }
 
+# @FUNCTION: check_sig_force
+# @INTERNAL
+# @DESCRIPTION:
+# Check if kernel requires module signing and die
+# if module is not going to be signed.
+check_sig_force() {
+       debug-print-function ${FUNCNAME} $*
+
+       if linux_chkconfig_present MODULE_SIG_FORCE; then
+               if use !module-sign; then
+                       ewarn ""
+                       ewarn "Kernel requires all modules to be signed and 
verified"
+                       ewarn "please enable USE=\"module-sign\""
+                       ewarn "otherwise loading the module will fail"
+                       die "signature required"
+               fi
+       fi
+}
+
 # @FUNCTION: use_m
 # @RETURN: true or false
 # @DESCRIPTION:
@@ -352,6 +397,28 @@ get-KERNEL_CC() {
        echo "${kernel_cc}"
 }
 
+# @FUNCTION: sign_module
+# @DESCRIPTION:
+# Sign a kernel module if enabled and supported, or just silently ignore the 
request and do nothing.
+# @USAGE: <filename>
+sign_module() {
+       debug-print-function ${FUNCNAME} $*
+
+       if use module-sign; then
+               local sig_hash sig_pem sig_x509 modulename
+               sig_hash=$(linux_chkconfig_string MODULE_SIG_HASH)
+               sig_pem="${KV_DIR}/certs/signing_key.pem"
+               sig_x509="${KV_DIR}/certs/signing_key.x509"
+               modulename=$(basename "${1}")
+
+               einfo "Signing ${modulename}"
+               "${KV_DIR}"/scripts/sign-file \
+               "${KERNEL_MODULE_SIG_HASH:-${sig_hash//\"/}}" \
+               "${KERNEL_MODULE_SIG_PEM:-${sig_pem}}" \
+               "${KERNEL_MODULE_SIG_X509:-${sig_x509}}" \
+               "${1}" || die "Signing ${modulename} failed"
+       fi
+}
 # internal function
 #
 # FUNCTION:
@@ -583,12 +650,17 @@ linux-mod_pkg_setup() {
        # External modules use kernel symbols (bug #591832)
        CONFIG_CHECK+=" !TRIM_UNUSED_KSYMS"
 
+       # if signature is requested, check if kernel actually supports it
+       use module-sign && CONFIG_CHECK+=" MODULE_SIG"
+
        linux-info_pkg_setup;
        require_configured_kernel
        check_kernel_built;
        strip_modulenames;
        [[ -n ${MODULE_NAMES} ]] && check_modules_supported
        set_kvobj;
+       use module-sign && export STRIP_MASK="*.${KV_OBJ}";
+       check_sig_force;
        # Commented out with permission from johnm until a fixed version for 
arches
        # who intentionally use different kernel and userland compilers can be
        # introduced - Jason Wever <we...@gentoo.org>, 23 Oct 2005
@@ -716,8 +788,9 @@ linux-mod_src_install() {
 
                einfo "Installing ${modulename} module"
                cd "${objdir}" || die "${objdir} does not exist"
-               insinto /lib/modules/${KV_FULL}/${libdir}
-               doins ${modulename}.${KV_OBJ} || die "doins 
${modulename}.${KV_OBJ} failed"
+               sign_module "${modulename}.${KV_OBJ}"
+               insinto /lib/modules/"${KV_FULL}/${libdir}"
+               doins "${modulename}.${KV_OBJ}" || die "doins 
${modulename}.${KV_OBJ} failed"
                cd "${OLDPWD}"
 
                generate_modulesd "${objdir}/${modulename}"

Reply via email to