public inbox for gentoo-dev@lists.gentoo.org
 help / color / mirror / Atom feed
From: Georgy Yakovlev <ya@sysdump.net>
To: gentoo-dev@lists.gentoo.org
Subject: Re: [gentoo-dev] Re: [PATCH] linux-mod.eclass: support module signing
Date: Fri, 20 Apr 2018 01:01:58 -0700	[thread overview]
Message-ID: <1524211318.12380.2.camel@sysdump.net> (raw)
In-Reply-To: <1524203783.1130.8.camel@gentoo.org>

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: <filename>
+# @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 <weeve@gentoo.org>, 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


      reply	other threads:[~2018-04-20  8:02 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-04-14 21:25 [gentoo-dev] [PATCH] linux-mod.eclass: support module signing Georgy Yakovlev
2018-04-15 18:13 ` NP-Hardass
2018-04-20  5:42 ` [gentoo-dev] " Georgy Yakovlev
2018-04-20  5:56   ` Michał Górny
2018-04-20  8:01     ` Georgy Yakovlev [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1524211318.12380.2.camel@sysdump.net \
    --to=ya@sysdump.net \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox