Gentoo Archives: gentoo-dev

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

Replies

Subject Author
Re: [gentoo-dev] Re: [PATCH] linux-mod.eclass: support module signing Georgy Yakovlev <ya@×××××××.net>