Gentoo Archives: gentoo-dev

From: Georgy Yakovlev <ya@×××××××.net>
To: gentoo-dev@l.g.o
Cc: gentoo-kernel@l.g.o
Subject: [gentoo-dev] Re: [PATCH] linux-mod.eclass: support module signing
Date: Fri, 20 Apr 2018 05:42:38
Message-Id: 1524202944.129809.17.camel@sysdump.net
In Reply to: [gentoo-dev] [PATCH] linux-mod.eclass: support module signing by Georgy Yakovlev
1 On Sat, 2018-04-14 at 14:25 -0700, Georgy Yakovlev wrote:
2
3 Second version, with safety checks and simplified logic.
4 Fixed most issues of the first patch.
5
6 Now only use single optional make.conf variable with the path to the
7 key.
8 Rest of parameters are magically extracted from .config or derived from
9 the key itself. So generally it just works.
10
11 got rid of STRIP_MASK, all signing happens in pkg_preinst, that way the
12 checksum of installed file is calculated with signature appended.
13 now works for packages that do not use linux-mod_src_install (zfs & co)
14
15
16 Thanks to NP-Hardass for initial review and suggestions.
17
18
19 > Hi,
20 >
21 > There is an old bug[1] to support
22 > linux kernel module signing at install.
23 >
24 > And here is my first attempt to modify an eclass.
25 > Need proper input on it and a kick in the right direction.
26 >
27 > Add 3 variables, settable by users if they keep keys somewhere safe.
28 > Otherwise it just works with the auto-generated keys
29 > if CONFIG_MODULE_SIG=y and vars are unset.
30 >
31 > eclass will die if kernel requires a signed module,
32 > but signing is not requested.
33 >
34 >
35 > Known problems:
36 >
37 > Packages that do not use linux-mod_src_install() will not sign
38 > the modules,
39 > But those packages will still inherit module-sign useflag.
40 > It's misleading and I'm not sure how to fix that.
41 > Examples : sys-kernel/spl, sys-fs/zfs-kmod
42 >
43 > May need additional handling of KBUILD_SIGN_PIN variable[2],
44 > which can be set to hold the passphrase to the key. But it may end up
45 > in vdb environment files, not sure how to handle that or if it worth
46 > it
47 >
48 > not eapi-7 ready because of STRIP_MASK usage.
49 > will need to cover this case as well, probably later.
50 >
51 > older (<4.3.3) kernels use perl to sign modules, not sure if it's
52 > worth
53 > supporting old kernels, there is no gentoo-sources in the tree old
54 > enough, except masked 4.1
55 > there are old vanilla-sources that will be affected by this.
56 >
57 >
58 > [1] https://bugs.gentoo.org/447352
59 > [2] https://www.kernel.org/doc/html/v4.16/admin-guide/module-signing.html
60
61 diff --git a/eclass/linux-mod.eclass b/eclass/linux-mod.eclass
62 index bf580cf4cfa9..8197654081cc 100644
63 --- a/eclass/linux-mod.eclass
64 +++ b/eclass/linux-mod.eclass
65 @@ -132,6 +132,16 @@
66 # @DESCRIPTION:
67 # It's a read-only variable. It contains the extension of the kernel modules.
68
69 +# @ECLASS-VARIABLE: KERNEL_MODULE_SIG_KEY
70 +# @DEFAULT_UNSET
71 +# @DESCRIPTION:
72 +# A string, containing absolute path to the private key file.
73 +# Defaults to value of CONFIG_MODULE_SIG_KEY extracted from .config
74 +# Can be set by user in make.conf
75 +# Example:
76 +# KERNEL_MODULE_SIG_KEY="/secure/location/keys/kernel.pem"
77 +# Assumes that "/secure/location/keys/kernel.x509" is a matching pubkey.
78 +
79 inherit eutils linux-info multilib
80 EXPORT_FUNCTIONS pkg_setup pkg_preinst pkg_postinst src_install src_compile pkg_postrm
81
82 @@ -144,12 +154,13 @@ esac
83 0) die "EAPI=${EAPI} is not supported with MODULES_OPTIONAL_USE_IUSE_DEFAULT due to lack of IUSE defaults" ;;
84 esac
85
86 -IUSE="kernel_linux ${MODULES_OPTIONAL_USE:+${_modules_optional_use_iuse_default}}${MODULES_OPTIONAL_USE}"
87 +IUSE="module-sign kernel_linux ${MODULES_OPTIONAL_USE:+${_modules_optional_use_iuse_default}}${MODULES_OPTIONAL_USE}"
88 SLOT="0"
89 RDEPEND="${MODULES_OPTIONAL_USE}${MODULES_OPTIONAL_USE:+? (} kernel_linux? ( virtual/modutils ) ${MODULES_OPTIONAL_USE:+)}"
90 DEPEND="${RDEPEND}
91 ${MODULES_OPTIONAL_USE}${MODULES_OPTIONAL_USE:+? (}
92 sys-apps/sed
93 + module-sign? ( || ( dev-libs/openssl dev-libs/libressl ) )
94 kernel_linux? ( virtual/linux-sources )
95 ${MODULES_OPTIONAL_USE:+)}"
96
97 @@ -352,6 +363,93 @@ get-KERNEL_CC() {
98 echo "${kernel_cc}"
99 }
100
101 +# @FUNCTION: check_sig_force
102 +# @INTERNAL
103 +# @DESCRIPTION:
104 +# Check if kernel requires module signing and die
105 +# if module is not going to be signed.
106 +check_sig_force() {
107 + debug-print-function ${FUNCNAME} $*
108 +
109 + if linux_chkconfig_present MODULE_SIG_FORCE; then
110 + if use !module-sign; then
111 + ewarn "kernel .config has MODULE_SIG_FORCE=y option set"
112 + ewarn "This means that kernel requires all modules"
113 + ewarn "to be signed and verified before loading"
114 + ewarn "please enable USE=\"module-sign\" or reconfigure your kernel"
115 + ewarn "otherwise loading the module will fail"
116 + die "signature required"
117 + fi
118 + fi
119 +}
120 +
121 +# @FUNCTION: sign_module
122 +# @INTERNAL
123 +# @DESCRIPTION:
124 +# Sign a kernel module
125 +# @USAGE: <filename>
126 +sign_module() {
127 + debug-print-function ${FUNCNAME} $*
128 +
129 + local dotconfig_sig_hash dotconfig_sig_key
130 + local sign_binary_path sig_key_path sig_x509_path
131 + local module
132 +
133 + # extract values from kernel .config
134 + # extracted key path is not full, e.g. "certs/signing_key.pem"
135 + dotconfig_sig_hash="$(linux_chkconfig_string MODULE_SIG_HASH)"
136 + dotconfig_sig_key="$(linux_chkconfig_string MODULE_SIG_KEY)"
137 +
138 + # strip out double quotes, sign-file binary chokes on them
139 + dotconfig_sig_hash=${dotconfig_sig_hash//\"/}
140 + dotconfig_sig_key=${dotconfig_sig_key//\"/}
141 +
142 + sign_binary_path="${KV_OUT_DIR}/scripts/sign-file"
143 + sig_key_path="${KERNEL_MODULE_SIG_KEY:-${KV_OUT_DIR}/${dotconfig_sig_key}}"
144 + sig_x509_path="${sig_key_path/.pem/.x509}"
145 +
146 + module=$(basename "${1%.${KV_OBJ}}")
147 +
148 + # some checks, because sign-file is dumb and produces cryptic errors
149 + [ -w "${1}" ] || die "${1} not found or not writable"
150 + grep -qFL '~Module signature appended~' "${1}" && die "${module} already signed"
151 + [ -x "${sign_binary_path}" ] || die "${sign_binary_path} not found or not executable"
152 + [ -e "${sig_key_path}" ] || die "Private key ${sig_key_path} not found or not readable"
153 + [ -e "${sig_x509_path}" ] || die "Public key ${sig_x509_path} not found or not readable"
154 +
155 + einfo "Signing ${module} using ${sig_key_path}:${dotconfig_sig_hash}"
156 + "${sign_binary_path}" \
157 + "${dotconfig_sig_hash}" "${sig_key_path}" "${sig_x509_path}" \
158 + "${1}" || die "Signing ${module} failed"
159 +}
160 +
161 +# @FUNCTION: sign_all_modules
162 +# @INTERNAL
163 +# @DESCRIPTION:
164 +# Signs all unsigned modules
165 +# Must be called in pkg_preinst.
166 +sign_all_modules() {
167 + debug-print-function ${FUNCNAME} $*
168 +
169 + [ -z "${KV_OBJ}" ] && set_kvobj;
170 + require_configured_kernel;
171 + check_kernel_built;
172 +
173 + local module
174 + local modules
175 +
176 + pushd "${ED}" > /dev/null || die
177 + modules=$(find "lib/modules/${KV_FULL}" -name "*.${KV_OBJ}" 2>/dev/null)
178 + if [[ -n ${modules} ]]; then
179 + for module in ${modules}; do
180 + sign_module "${module}"
181 + done
182 + else
183 + ewarn 'QA: list of modules to sign is empty, pease report a bug'
184 + fi
185 + popd > /dev/null || die
186 +}
187 +
188 # internal function
189 #
190 # FUNCTION:
191 @@ -583,12 +681,16 @@ linux-mod_pkg_setup() {
192 # External modules use kernel symbols (bug #591832)
193 CONFIG_CHECK+=" !TRIM_UNUSED_KSYMS"
194
195 + # if signature is requested, check if kernel actually supports it
196 + use module-sign && CONFIG_CHECK+=" MODULE_SIG"
197 +
198 linux-info_pkg_setup;
199 require_configured_kernel
200 check_kernel_built;
201 strip_modulenames;
202 [[ -n ${MODULE_NAMES} ]] && check_modules_supported
203 set_kvobj;
204 + check_sig_force;
205 # Commented out with permission from johnm until a fixed version for arches
206 # who intentionally use different kernel and userland compilers can be
207 # introduced - Jason Wever <weeve@g.o>, 23 Oct 2005
208 @@ -716,8 +818,8 @@ linux-mod_src_install() {
209
210 einfo "Installing ${modulename} module"
211 cd "${objdir}" || die "${objdir} does not exist"
212 - insinto /lib/modules/${KV_FULL}/${libdir}
213 - doins ${modulename}.${KV_OBJ} || die "doins ${modulename}.${KV_OBJ} failed"
214 + insinto /lib/modules/"${KV_FULL}/${libdir}"
215 + doins "${modulename}.${KV_OBJ}" || die "doins ${modulename}.${KV_OBJ} failed"
216 cd "${OLDPWD}"
217
218 generate_modulesd "${objdir}/${modulename}"
219 @@ -733,6 +835,8 @@ linux-mod_pkg_preinst() {
220
221 [ -d "${D}lib/modules" ] && UPDATE_DEPMOD=true || UPDATE_DEPMOD=false
222 [ -d "${D}lib/modules" ] && UPDATE_MODULEDB=true || UPDATE_MODULEDB=false
223 + check_sig_force
224 + use module-sign && sign_all_modules
225 }
226
227 # @FUNCTION: linux-mod_pkg_postinst

Replies

Subject Author
Re: [gentoo-dev] Re: [PATCH] linux-mod.eclass: support module signing "Michał Górny" <mgorny@g.o>