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 262E41382C5 for ; Fri, 20 Apr 2018 05:42:38 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 25667E08DF; Fri, 20 Apr 2018 05:42:32 +0000 (UTC) Received: from mail-io0-x22d.google.com (mail-io0-x22d.google.com [IPv6:2607:f8b0:4001:c06::22d]) (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 B3EFCE08DA for ; Fri, 20 Apr 2018 05:42:31 +0000 (UTC) Received: by mail-io0-x22d.google.com with SMTP id v13-v6so9278695iob.6 for ; Thu, 19 Apr 2018 22:42:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sysdump.net; s=google; h=message-id:subject:from:to:cc:date:in-reply-to:references :mime-version:content-transfer-encoding; bh=nD4nfmp+Kwy6wKUfxWBCh1bOrgVRTck4lDa0he8fVsw=; b=CtIzfvsSJF88Y67++I+O4Ath9h2WzqW7u3N/2yFVTSqPbpcA5H9nuI2xY7CnTXjhCH MBk+siVRDleMSRCvQO504Oi3CSVkWXGqA5rpO/4Pj9xcNBpxPWlXBl129OZHRMFwSFg/ ZaKyYyuKvhjhF7anuqeid4GZJI+oh/Aj/X8qhyO7i20NsCi8d5odBM/1W2Y68uhJHgQM SeH9LznhHCYRYAeohtEEYpke8ea3i4K/2Zo0OhM7KPB2DeSM6SwyD6ac4jMJoagVmesT MSgfR3SbDQZDvci5SADF1elTeUksx2lkPo/G2twUjmSK/I6jcXJU8ZYcW12VoeRGEz9q TLfQ== 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:cc:date:in-reply-to :references:mime-version:content-transfer-encoding; bh=nD4nfmp+Kwy6wKUfxWBCh1bOrgVRTck4lDa0he8fVsw=; b=jylwK20VcJt84b0ug3w411wyEi3okS0cq7lyblKp/c29408WyPhkJ1xfPbydCerRur FU7NUJAVwHyROckd6YsBWwd6jPoJDDgwYLSEZU8ZDYjy+xpTk74fWLFx00pPGKCZP8lE aL9FNkcEJ82Uq/LViyBKfzMhxgWcFI9Zo9wk9A0XPIDxogTc5bMNQuW/yPcZQPiHNR9y WmXf7MN08QyPCz/teDjIEY6H1NMOKlHTg2m0ObYgQOfjuJKbWkyRiYkDgRi4lNud+RMV BNqgXlR7cgRpvSir+Lw9ZP3+BBHlqGidFvYbzkjNAw3zeP8KiSVY9osDrgMI8fxSuroQ Dh6Q== X-Gm-Message-State: ALQs6tC8R8GX7yccmWQ1d5eNxsQvAENFL5xoBbbMMkyLRgh1KYMYwz7N 8V7EX7XZ8lQ6rSC6zW40Pt47dIIOCxg= X-Google-Smtp-Source: AB8JxZpDgJotjsntN4RCRRj44f+u94VQpijHfHfYofDEr35CrKeyD313m0Jxxw//nicoYBQQxzpNlw== X-Received: by 2002:a6b:2b10:: with SMTP id r16-v6mr8988113ior.204.1524202950360; Thu, 19 Apr 2018 22:42:30 -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 b187-v6sm503507ita.5.2018.04.19.22.42.27 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Thu, 19 Apr 2018 22:42:29 -0700 (PDT) Message-ID: <1524202944.129809.17.camel@sysdump.net> Subject: [gentoo-dev] Re: [PATCH] linux-mod.eclass: support module signing From: Georgy Yakovlev To: gentoo-dev@lists.gentoo.org Cc: gentoo-kernel@lists.gentoo.org Date: Thu, 19 Apr 2018 22:42:24 -0700 In-Reply-To: <1523741109.12403.28.camel@sysdump.net> References: <1523741109.12403.28.camel@sysdump.net> 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: 09bb1789-6233-4fb7-9ce5-1aff60f8a9d7 X-Archives-Hash: 5c362f975d01976ab8436a23d72b55c1 On Sat, 2018-04-14 at 14:25 -0700, Georgy Yakovlev wrote: Second version, with safety checks and simplified logic. Fixed most issues of the first patch. Now only use single optional make.conf variable with the path to the key. Rest of parameters are magically extracted from .config or derived from the key itself. So generally it just works. got rid of STRIP_MASK, all signing happens in pkg_preinst, that way the checksum of installed file is calculated with signature appended. now works for packages that do not use linux-mod_src_install (zfs & co) Thanks to NP-Hardass for initial review and suggestions. > 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..8197654081cc 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 +# @DEFAULT_UNSET +# @DESCRIPTION: +# A string, containing absolute path to the private key file. +# Defaults to value of CONFIG_MODULE_SIG_KEY extracted from .config +# Can be set by user in make.conf +# 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,93 @@ 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 + ewarn "kernel .config has MODULE_SIG_FORCE=y option set" + ewarn "This means that kernel requires all modules" + ewarn "to be signed and verified before loading" + ewarn "please enable USE=\"module-sign\" or reconfigure your kernel" + ewarn "otherwise loading the module will fail" + die "signature required" + fi + fi +} + +# @FUNCTION: sign_module +# @INTERNAL +# @DESCRIPTION: +# Sign a kernel module +# @USAGE: +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=$(basename "${1%.${KV_OBJ}}") + + # 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" + [ -e "${sig_key_path}" ] || die "Private key ${sig_key_path} not found or not readable" + [ -e "${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 + local modules + + pushd "${ED}" > /dev/null || die + modules=$(find "lib/modules/${KV_FULL}" -name "*.${KV_OBJ}" 2>/dev/null) + if [[ -n ${modules} ]]; then + for module in ${modules}; do + sign_module "${module}" + done + else + ewarn 'QA: list of modules to sign is empty, pease report a bug' + fi + popd > /dev/null || die +} + # internal function # # FUNCTION: @@ -583,12 +681,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 +818,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 +835,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