From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 15A2D1382C5 for ; Fri, 20 Apr 2018 08:02:12 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id AAC6EE0904; Fri, 20 Apr 2018 08:02:05 +0000 (UTC) Received: from mail-pg0-x241.google.com (mail-pg0-x241.google.com [IPv6:2607:f8b0:400e:c05::241]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 2CBC3E08F3 for ; Fri, 20 Apr 2018 08:02:04 +0000 (UTC) Received: by mail-pg0-x241.google.com with SMTP id j11so3710128pgf.2 for ; Fri, 20 Apr 2018 01:02:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sysdump.net; s=google; h=message-id:subject:from:to:date:in-reply-to:references:mime-version :content-transfer-encoding; bh=REpdX3Jf7UMNrJtD8FdsWwb8Sq5Mp26l0YCc7kjICuk=; b=boHTei+XqbnD8CLA0iMBErlsPzdgPYQNSeBdhf1mKRXHwj40ZRSZMWCmq81BXchjX8 QaG9ehg+DmevIGOxNrNO6nWGo3der1XyZyBn03/aMxspEaN4BHw9GZvTx/DFC8v+D276 0TZoPMa83GqvNg6uM0r8j4b8uZQERY3FuP4z0/stangQE88rgbamEcqJCeCzjf5tEeP2 9VyQ3vx+W24RoY7bQsHVFS5Knon5qqLVv1mHHXezwDpGTaO2J0dmczU1hxgL2gf800vC 2vPWEfPVgC/zQNf8iz1W7NQcW8Gl9J0YaYKqjBzU6nCNO2p7P7g+L+XjkEUSD3dDjbgx 88SQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:message-id:subject:from:to:date:in-reply-to :references:mime-version:content-transfer-encoding; bh=REpdX3Jf7UMNrJtD8FdsWwb8Sq5Mp26l0YCc7kjICuk=; b=rvQYu89S2Q6SlH39XFu+2+APwyfs3K21MG2NCoEKTf/ajkumE/hR4yibF1PhIdpNRz aG3VDS3/hdJGZSfpU0Xmmv0O5xszJTK6Uib/Bypu+Dr22rG9bcjH66Ana6ubsxnyjj33 HFL4miKxmrKZBnhrbE6m9vjrevlUBMZiummd4Z3Pdux+6fvX2JgxnqEilbldbkl8cZM4 Gk6xxdcvgH0F5WVCEhFa2Adv15iveHKwlspGITrVtb5aAwJ3N1dVqBtIQsVNvOpqBcjh 6D3rt9UvJBWq4zCv3Vfj1EsP7dbs7d42JMVyF85+KiN3ZL+XRl/57Kv8uTuur5yRnVA9 EufQ== X-Gm-Message-State: ALQs6tDuGpgpJIRDIhBM93DS6QpbyLUok025n5kDbscE94T9OdzW+q0V taPiOeGBmT1walJYtr42t1iskj4d0kw= X-Google-Smtp-Source: AIpwx4+o/idXLqh7VLj/dxyzo0SMDQ7nD1D1/lwM5X0/JyCL97PEFfv5IETKXE2EvFYcA/rDbQYDuA== X-Received: by 10.99.116.89 with SMTP id e25mr7829234pgn.43.1524211323305; Fri, 20 Apr 2018 01:02:03 -0700 (PDT) Received: from usg.local.sysdump.net.local.sysdump.net (cpe-75-83-91-39.socal.res.rr.com. [75.83.91.39]) by smtp.gmail.com with ESMTPSA id m6sm8405780pgu.51.2018.04.20.01.02.00 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 20 Apr 2018 01:02:02 -0700 (PDT) Message-ID: <1524211318.12380.2.camel@sysdump.net> Subject: Re: [gentoo-dev] Re: [PATCH] linux-mod.eclass: support module signing From: Georgy Yakovlev To: gentoo-dev@lists.gentoo.org Date: Fri, 20 Apr 2018 01:01:58 -0700 In-Reply-To: <1524203783.1130.8.camel@gentoo.org> References: <1523741109.12403.28.camel@sysdump.net> <1524202944.129809.17.camel@sysdump.net> <1524203783.1130.8.camel@gentoo.org> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.24.6 Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-dev@lists.gentoo.org Reply-to: gentoo-dev@lists.gentoo.org Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-Archives-Salt: 7c9621f7-71c5-485d-86bb-6df1798b126c X-Archives-Hash: a14bccebdc5281c91e0ce27112b9b2f7 Version 3 with fixes as requested by mgorny, thanks for review! Overall I think eclass needs some love, as and uses semicolons, single square brackets, quoting and eclass descriptions are a bit inconsistent, but that's out of scope of this patch right now. I think all the new code I've added follows up-to-date standards now and no longer uses old syntax. diff --git a/eclass/linux-mod.eclass b/eclass/linux-mod.eclass index bf580cf4cfa9..5df15561b9e6 100644 --- a/eclass/linux-mod.eclass +++ b/eclass/linux-mod.eclass @@ -132,6 +132,16 @@ # @DESCRIPTION: # It's a read-only variable. It contains the extension of the kernel modules. +# @ECLASS-VARIABLE: KERNEL_MODULE_SIG_KEY +# @USER_VARIABLE +# @DEFAULT_UNSET +# @DESCRIPTION: +# A string, containing absolute path to the private key file. +# Defaults to value of CONFIG_MODULE_SIG_KEY extracted from .config +# Example: +# KERNEL_MODULE_SIG_KEY="/secure/location/keys/kernel.pem" +# Assumes that "/secure/location/keys/kernel.x509" is a matching pubkey. + inherit eutils linux-info multilib EXPORT_FUNCTIONS pkg_setup pkg_preinst pkg_postinst src_install src_compile pkg_postrm @@ -144,12 +154,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:+)}" @@ -352,6 +363,84 @@ get-KERNEL_CC() { echo "${kernel_cc}" } +# @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 + eerror "kernel .config has MODULE_SIG_FORCE=y option set" + eerror "This means that kernel requires all modules" + eerror "to be signed and verified before loading" + eerror "please enable USE=\"module-sign\" or reconfigure your kernel" + eerror "otherwise loading the module will fail" + die "signature required" + fi + fi +} + +# @FUNCTION: _sign_module +# @INTERNAL +# @USAGE: +# @DESCRIPTION: +# Sign a kernel module +_sign_module() { + debug-print-function ${FUNCNAME} "${@}" + + local dotconfig_sig_hash dotconfig_sig_key + local sign_binary_path sig_key_path sig_x509_path + local module + + # extract values from kernel .config + # extracted key path is not full, e.g. "certs/signing_key.pem" + dotconfig_sig_hash="$(linux_chkconfig_string MODULE_SIG_HASH)" + dotconfig_sig_key="$(linux_chkconfig_string MODULE_SIG_KEY)" + + # strip out double quotes, sign-file binary chokes on them + dotconfig_sig_hash=${dotconfig_sig_hash//\"/} + dotconfig_sig_key=${dotconfig_sig_key//\"/} + + sign_binary_path="${KV_OUT_DIR}/scripts/sign-file" + sig_key_path="${KERNEL_MODULE_SIG_KEY:-${KV_OUT_DIR}/${dotconfig_sig_key}}" + sig_x509_path="${sig_key_path/.pem/.x509}" + + module=${1##*/} + + # some checks, because sign-file is dumb and produces cryptic errors + [[ -w "${1}" ]] || die "${1} not found or not writable" + grep -qFL '~Module signature appended~' "${1}" && die "${module} already signed" + [[ -x "${sign_binary_path}" ]] || die "${sign_binary_path} not found or not executable" + [[ -r "${sig_key_path}" ]] || die "Private key ${sig_key_path} not found or not readable" + [[ -r "${sig_x509_path}" ]] || die "Public key ${sig_x509_path} not found or not readable" + + einfo "Signing ${module} using ${sig_key_path}:${dotconfig_sig_hash}" + "${sign_binary_path}" \ + "${dotconfig_sig_hash}" "${sig_key_path}" "${sig_x509_path}" \ + "${1}" || die "Signing ${module} failed" +} + +# @FUNCTION: _sign_all_modules +# @INTERNAL +# @DESCRIPTION: +# Signs all unsigned modules +# Must be called in pkg_preinst. +_sign_all_modules() { + debug-print-function ${FUNCNAME} "${@}" + + [[ -z "${KV_OBJ}" ]] && set_kvobj + require_configured_kernel + check_kernel_built + + local module + while read -rd '' module; do + _sign_module "${module}" + done < <(find "${ED}/lib/modules/${KV_FULL}" -name "*.${KV_OBJ}" -print0) +} + # internal function # # FUNCTION: @@ -583,12 +672,16 @@ 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; + _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 , 23 Oct 2005 @@ -716,8 +809,8 @@ 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" + insinto /lib/modules/"${KV_FULL}/${libdir}" + doins "${modulename}.${KV_OBJ}" || die "doins ${modulename}.${KV_OBJ} failed" cd "${OLDPWD}" generate_modulesd "${objdir}/${modulename}" @@ -733,6 +826,8 @@ linux-mod_pkg_preinst() { [ -d "${D}lib/modules" ] && UPDATE_DEPMOD=true || UPDATE_DEPMOD=false [ -d "${D}lib/modules" ] && UPDATE_MODULEDB=true || UPDATE_MODULEDB=false + _check_sig_force + use module-sign && _sign_all_modules } # @FUNCTION: linux-mod_pkg_postinst