On 04/14/2018 05:25 PM, Georgy Yakovlev wrote:
> 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
>  

These KV_DIRs should be KV_OUT_DIRs, as they are objects only available
after building the kernel and thus if KV_OUT_DIR != KV_DIR, this will fail.

Additionally, sig_pem and sig_x509 should be derived from MODULE_SIG_KEY
by default.
> @@ -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:


The documentation for linux_chkconfig_present states "If
linux_config_exists returns false, the results of this are UNDEFINED.
You MUST call linux_config_exists first."
> @@ -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:

These KV_DIRs should be KV_OUT_DIRs, as they are objects only available
after building the kernel and thus if KV_OUT_DIR != KV_DIR, this will fail.

The documentation for linux_chkconfig_string states "If
linux_config_exists returns false, the results of this are UNDEFINED.
You MUST call linux_config_exists first."

Additionally, sig_pem and sig_x509 should be derived from MODULE_SIG_KEY.

> @@ -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}"
> 


You can work around the STRIP_MASK issue by performing the steps in
pkg_postinst after the stripped modules have been installed. You could
probably save a list of installed modules a la
gnome2_gconf_savelist and then pull that up in postinst and sign the
desired modules there.

-- 
NP-Hardass

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to