1 |
On 04/14/2018 05:25 PM, Georgy Yakovlev wrote: |
2 |
> Hi, |
3 |
> |
4 |
> There is an old bug[1] to support |
5 |
> linux kernel module signing at install. |
6 |
> |
7 |
> And here is my first attempt to modify an eclass. |
8 |
> Need proper input on it and a kick in the right direction. |
9 |
> |
10 |
> Add 3 variables, settable by users if they keep keys somewhere safe. |
11 |
> Otherwise it just works with the auto-generated keys |
12 |
> if CONFIG_MODULE_SIG=y and vars are unset. |
13 |
> |
14 |
> eclass will die if kernel requires a signed module, |
15 |
> but signing is not requested. |
16 |
> |
17 |
> |
18 |
> Known problems: |
19 |
> |
20 |
> Packages that do not use linux-mod_src_install() will not sign |
21 |
> the modules, |
22 |
> But those packages will still inherit module-sign useflag. |
23 |
> It's misleading and I'm not sure how to fix that. |
24 |
> Examples : sys-kernel/spl, sys-fs/zfs-kmod |
25 |
> |
26 |
> May need additional handling of KBUILD_SIGN_PIN variable[2], |
27 |
> which can be set to hold the passphrase to the key. But it may end up |
28 |
> in vdb environment files, not sure how to handle that or if it worth it |
29 |
> |
30 |
> not eapi-7 ready because of STRIP_MASK usage. |
31 |
> will need to cover this case as well, probably later. |
32 |
> |
33 |
> older (<4.3.3) kernels use perl to sign modules, not sure if it's worth |
34 |
> supporting old kernels, there is no gentoo-sources in the tree old |
35 |
> enough, except masked 4.1 |
36 |
> there are old vanilla-sources that will be affected by this. |
37 |
> |
38 |
> |
39 |
> [1] https://bugs.gentoo.org/447352 |
40 |
> [2] https://www.kernel.org/doc/html/v4.16/admin-guide/module-signing.html |
41 |
> |
42 |
> diff --git a/eclass/linux-mod.eclass b/eclass/linux-mod.eclass |
43 |
> index bf580cf4cfa9..211b0496f528 100644 |
44 |
> --- a/eclass/linux-mod.eclass |
45 |
> +++ b/eclass/linux-mod.eclass |
46 |
> @@ -14,7 +14,7 @@ |
47 |
> # required to install external modules against a kernel source |
48 |
> # tree. |
49 |
> |
50 |
> -# A Couple of env vars are available to effect usage of this eclass |
51 |
> +# Several env vars are available to effect usage of this eclass |
52 |
> # These are as follows: |
53 |
> |
54 |
> # @ECLASS-VARIABLE: MODULES_OPTIONAL_USE |
55 |
> @@ -132,6 +132,31 @@ |
56 |
> # @DESCRIPTION: |
57 |
> # It's a read-only variable. It contains the extension of the kernel modules. |
58 |
> |
59 |
> +# @ECLASS-VARIABLE: KERNEL_MODULE_SIG_HASH |
60 |
> +# @DEFAULT_UNSET |
61 |
> +# @DESCRIPTION: |
62 |
> +# A string to control signing algorithm |
63 |
> +# Possible values: sha1:sha224:sha256:sha384:sha512 |
64 |
> +# Defaults to value extracted from .config |
65 |
> +# Can be set by user in make.conf, as it can differ from kernel's. |
66 |
> +# In case of overriding this it's users responsibility to make sure |
67 |
> +# that kernel supports desired hash algo |
68 |
> + |
69 |
> +# @ECLASS-VARIABLE: KERNEL_MODULE_SIG_PEM |
70 |
> +# @DEFAULT_UNSET |
71 |
> +# @DESCRIPTION: |
72 |
> +# A string, containing path to the private key filename or PKCS#11 URI |
73 |
> +# Defaults to ${KV_DIR}/certs/signing_key.pem} if unset. |
74 |
> +# Can be set by user in make.conf |
75 |
> + |
76 |
> +# @ECLASS-VARIABLE: KERNEL_MODULE_SIG_X509 |
77 |
> +# @DEFAULT_UNSET |
78 |
> +# @DESCRIPTION: |
79 |
> +# A string, containing path to the public key filename |
80 |
> +# Defaults to ${KV_DIR}/certs/signing_key.x509} if unset. |
81 |
> +# Can be set by user in make.conf |
82 |
> + |
83 |
> + |
84 |
> inherit eutils linux-info multilib |
85 |
> EXPORT_FUNCTIONS pkg_setup pkg_preinst pkg_postinst src_install src_compile pkg_postrm |
86 |
> |
87 |
|
88 |
These KV_DIRs should be KV_OUT_DIRs, as they are objects only available |
89 |
after building the kernel and thus if KV_OUT_DIR != KV_DIR, this will fail. |
90 |
|
91 |
Additionally, sig_pem and sig_x509 should be derived from MODULE_SIG_KEY |
92 |
by default. |
93 |
> @@ -144,12 +169,13 @@ esac |
94 |
> 0) die "EAPI=${EAPI} is not supported with MODULES_OPTIONAL_USE_IUSE_DEFAULT due to lack of IUSE defaults" ;; |
95 |
> esac |
96 |
> |
97 |
> -IUSE="kernel_linux ${MODULES_OPTIONAL_USE:+${_modules_optional_use_iuse_default}}${MODULES_OPTIONAL_USE}" |
98 |
> +IUSE="module-sign kernel_linux ${MODULES_OPTIONAL_USE:+${_modules_optional_use_iuse_default}}${MODULES_OPTIONAL_USE}" |
99 |
> SLOT="0" |
100 |
> RDEPEND="${MODULES_OPTIONAL_USE}${MODULES_OPTIONAL_USE:+? (} kernel_linux? ( virtual/modutils ) ${MODULES_OPTIONAL_USE:+)}" |
101 |
> DEPEND="${RDEPEND} |
102 |
> ${MODULES_OPTIONAL_USE}${MODULES_OPTIONAL_USE:+? (} |
103 |
> sys-apps/sed |
104 |
> + module-sign? ( || ( dev-libs/openssl dev-libs/libressl ) ) |
105 |
> kernel_linux? ( virtual/linux-sources ) |
106 |
> ${MODULES_OPTIONAL_USE:+)}" |
107 |
> |
108 |
> @@ -196,6 +222,25 @@ check_vermagic() { |
109 |
> fi |
110 |
> } |
111 |
> |
112 |
> +# @FUNCTION: check_sig_force |
113 |
> +# @INTERNAL |
114 |
> +# @DESCRIPTION: |
115 |
> +# Check if kernel requires module signing and die |
116 |
> +# if module is not going to be signed. |
117 |
> +check_sig_force() { |
118 |
> + debug-print-function ${FUNCNAME} $* |
119 |
> + |
120 |
> + if linux_chkconfig_present MODULE_SIG_FORCE; then |
121 |
> + if use !module-sign; then |
122 |
> + ewarn "" |
123 |
> + ewarn "Kernel requires all modules to be signed and verified" |
124 |
> + ewarn "please enable USE=\"module-sign\"" |
125 |
> + ewarn "otherwise loading the module will fail" |
126 |
> + die "signature required" |
127 |
> + fi |
128 |
> + fi |
129 |
> +} |
130 |
> + |
131 |
> # @FUNCTION: use_m |
132 |
> # @RETURN: true or false |
133 |
> # @DESCRIPTION: |
134 |
|
135 |
|
136 |
The documentation for linux_chkconfig_present states "If |
137 |
linux_config_exists returns false, the results of this are UNDEFINED. |
138 |
You MUST call linux_config_exists first." |
139 |
> @@ -352,6 +397,28 @@ get-KERNEL_CC() { |
140 |
> echo "${kernel_cc}" |
141 |
> } |
142 |
> |
143 |
> +# @FUNCTION: sign_module |
144 |
> +# @DESCRIPTION: |
145 |
> +# Sign a kernel module if enabled and supported, or just silently ignore the request and do nothing. |
146 |
> +# @USAGE: <filename> |
147 |
> +sign_module() { |
148 |
> + debug-print-function ${FUNCNAME} $* |
149 |
> + |
150 |
> + if use module-sign; then |
151 |
> + local sig_hash sig_pem sig_x509 modulename |
152 |
> + sig_hash=$(linux_chkconfig_string MODULE_SIG_HASH) |
153 |
> + sig_pem="${KV_DIR}/certs/signing_key.pem" |
154 |
> + sig_x509="${KV_DIR}/certs/signing_key.x509" |
155 |
> + modulename=$(basename "${1}") |
156 |
> + |
157 |
> + einfo "Signing ${modulename}" |
158 |
> + "${KV_DIR}"/scripts/sign-file \ |
159 |
> + "${KERNEL_MODULE_SIG_HASH:-${sig_hash//\"/}}" \ |
160 |
> + "${KERNEL_MODULE_SIG_PEM:-${sig_pem}}" \ |
161 |
> + "${KERNEL_MODULE_SIG_X509:-${sig_x509}}" \ |
162 |
> + "${1}" || die "Signing ${modulename} failed" |
163 |
> + fi |
164 |
> +} |
165 |
> # internal function |
166 |
> # |
167 |
> # FUNCTION: |
168 |
|
169 |
These KV_DIRs should be KV_OUT_DIRs, as they are objects only available |
170 |
after building the kernel and thus if KV_OUT_DIR != KV_DIR, this will fail. |
171 |
|
172 |
The documentation for linux_chkconfig_string states "If |
173 |
linux_config_exists returns false, the results of this are UNDEFINED. |
174 |
You MUST call linux_config_exists first." |
175 |
|
176 |
Additionally, sig_pem and sig_x509 should be derived from MODULE_SIG_KEY. |
177 |
|
178 |
> @@ -583,12 +650,17 @@ linux-mod_pkg_setup() { |
179 |
> # External modules use kernel symbols (bug #591832) |
180 |
> CONFIG_CHECK+=" !TRIM_UNUSED_KSYMS" |
181 |
> |
182 |
> + # if signature is requested, check if kernel actually supports it |
183 |
> + use module-sign && CONFIG_CHECK+=" MODULE_SIG" |
184 |
> + |
185 |
> linux-info_pkg_setup; |
186 |
> require_configured_kernel |
187 |
> check_kernel_built; |
188 |
> strip_modulenames; |
189 |
> [[ -n ${MODULE_NAMES} ]] && check_modules_supported |
190 |
> set_kvobj; |
191 |
> + use module-sign && export STRIP_MASK="*.${KV_OBJ}"; |
192 |
> + check_sig_force; |
193 |
> # Commented out with permission from johnm until a fixed version for arches |
194 |
> # who intentionally use different kernel and userland compilers can be |
195 |
> # introduced - Jason Wever <weeve@g.o>, 23 Oct 2005 |
196 |
> @@ -716,8 +788,9 @@ linux-mod_src_install() { |
197 |
> |
198 |
> einfo "Installing ${modulename} module" |
199 |
> cd "${objdir}" || die "${objdir} does not exist" |
200 |
> - insinto /lib/modules/${KV_FULL}/${libdir} |
201 |
> - doins ${modulename}.${KV_OBJ} || die "doins ${modulename}.${KV_OBJ} failed" |
202 |
> + sign_module "${modulename}.${KV_OBJ}" |
203 |
> + insinto /lib/modules/"${KV_FULL}/${libdir}" |
204 |
> + doins "${modulename}.${KV_OBJ}" || die "doins ${modulename}.${KV_OBJ} failed" |
205 |
> cd "${OLDPWD}" |
206 |
> |
207 |
> generate_modulesd "${objdir}/${modulename}" |
208 |
> |
209 |
|
210 |
|
211 |
You can work around the STRIP_MASK issue by performing the steps in |
212 |
pkg_postinst after the stripped modules have been installed. You could |
213 |
probably save a list of installed modules a la |
214 |
gnome2_gconf_savelist and then pull that up in postinst and sign the |
215 |
desired modules there. |
216 |
|
217 |
-- |
218 |
NP-Hardass |