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 |