1 |
This commit adds some eclass variables and private functions |
2 |
and a new global useflag. |
3 |
|
4 |
Example config, part of make.conf |
5 |
USE="... module-sign ..." |
6 |
KERNEL_MODULE_SIG_KEY="/secure/location/kernel.pem" |
7 |
|
8 |
And possible kernel options: |
9 |
|
10 |
CONFIG_MODULE_SIG=y |
11 |
CONFIG_MODULE_SIG_FORCE=y |
12 |
CONFIG_MODULE_SIG_ALL=y |
13 |
CONFIG_MODULE_SIG_SHA512=y |
14 |
CONFIG_MODULE_SIG_HASH="sha512" |
15 |
|
16 |
NOTE to libressl users: libressl does not support anything |
17 |
except CONFIG_MODULE_SIG_SHA1=y CONFIG_MODULE_SIG_HASH="sha1" |
18 |
|
19 |
Even if user does not follow key creation procedure and |
20 |
just enables module encryption while configuring kernel eclass "just works". |
21 |
|
22 |
All the signing happens in pkg_preinst. |
23 |
This means that binpkg users are expected to |
24 |
have keys and sign modules on target system, not on builder. |
25 |
|
26 |
I've been using this since March and have not encountered |
27 |
a single problem with various out-of-tree kernel modules |
28 |
Tested so far: |
29 |
virtualbox-modules |
30 |
nvidia-drivers |
31 |
zfs & co |
32 |
wireguard |
33 |
and many more |
34 |
|
35 |
If an ebuild uses Kbuild and/or runs linux-mod_pkg_preinst(), signing should work. |
36 |
|
37 |
All the signing happens as root, this means user can have the |
38 |
keys stored with secure permissions and mount as required. |
39 |
|
40 |
If user configured kernel to require signed modules the eclass |
41 |
will detect it and refuse to emerge if useflag is not enabled. |
42 |
|
43 |
I'll appreciate your testing and feedbak. |
44 |
|
45 |
NOTE to amdgpu users: if you use CONFIG_HSA_AMD, you'll want to have |
46 |
CONFIG_HSA_AMD=y |
47 |
|
48 |
having it as a module fails to sing for some reason, it's something in |
49 |
kernel/kbuild and not related to this eclass change. |
50 |
|
51 |
Closes: https://bugs.gentoo.org/447352 |
52 |
Signed-off-by: Georgy Yakovlev <gyakovlev@g.o> |
53 |
--- |
54 |
eclass/linux-mod.eclass | 109 ++++++++++++++++++++++++++++++++++++++-- |
55 |
profiles/use.desc | 1 + |
56 |
2 files changed, 106 insertions(+), 4 deletions(-) |
57 |
|
58 |
diff --git a/eclass/linux-mod.eclass b/eclass/linux-mod.eclass |
59 |
index e5b5ec782f0..540b55286f8 100644 |
60 |
--- a/eclass/linux-mod.eclass |
61 |
+++ b/eclass/linux-mod.eclass |
62 |
@@ -132,6 +132,20 @@ |
63 |
# @DESCRIPTION: |
64 |
# It's a read-only variable. It contains the extension of the kernel modules. |
65 |
|
66 |
+# @ECLASS-VARIABLE: KERNEL_MODULE_SIG_KEY |
67 |
+# @USER_VARIABLE |
68 |
+# @DEFAULT_UNSET |
69 |
+# @DESCRIPTION: |
70 |
+# A string, containing absolute path to the private key file. |
71 |
+# eclass will use value of CONFIG_MODULE_SIG_KEY extracted from .config |
72 |
+# if KERNEL_MODULE_SIG_KEY is not set by user. |
73 |
+# |
74 |
+# Example: |
75 |
+# @CODE |
76 |
+# KERNEL_MODULE_SIG_KEY="/secure/location/kernel.pem" |
77 |
+# @CODE |
78 |
+# Assumes that "/secure/location/kernel.x509" public key file exists. |
79 |
+ |
80 |
inherit eutils linux-info multilib |
81 |
EXPORT_FUNCTIONS pkg_setup pkg_preinst pkg_postinst src_install src_compile pkg_postrm |
82 |
|
83 |
@@ -144,13 +158,16 @@ esac |
84 |
0) die "EAPI=${EAPI} is not supported with MODULES_OPTIONAL_USE_IUSE_DEFAULT due to lack of IUSE defaults" ;; |
85 |
esac |
86 |
|
87 |
-IUSE="kernel_linux ${MODULES_OPTIONAL_USE:+${_modules_optional_use_iuse_default}}${MODULES_OPTIONAL_USE}" |
88 |
+IUSE="module-sign kernel_linux ${MODULES_OPTIONAL_USE:+${_modules_optional_use_iuse_default}}${MODULES_OPTIONAL_USE}" |
89 |
SLOT="0" |
90 |
RDEPEND="${MODULES_OPTIONAL_USE}${MODULES_OPTIONAL_USE:+? (} kernel_linux? ( virtual/modutils ) ${MODULES_OPTIONAL_USE:+)}" |
91 |
DEPEND="${RDEPEND} |
92 |
${MODULES_OPTIONAL_USE}${MODULES_OPTIONAL_USE:+? (} |
93 |
sys-apps/sed |
94 |
- kernel_linux? ( virtual/linux-sources virtual/libelf ) |
95 |
+ kernel_linux? ( |
96 |
+ virtual/linux-sources virtual/libelf |
97 |
+ module-sign? ( || ( dev-libs/openssl dev-libs/libressl ) ) |
98 |
+ ) |
99 |
${MODULES_OPTIONAL_USE:+)}" |
100 |
|
101 |
# eclass utilities |
102 |
@@ -352,6 +369,84 @@ get-KERNEL_CC() { |
103 |
echo "${kernel_cc}" |
104 |
} |
105 |
|
106 |
+# @FUNCTION: _check_sig_force |
107 |
+# @INTERNAL |
108 |
+# @DESCRIPTION: |
109 |
+# Check if kernel requires module signing and die |
110 |
+# if modules are not going to be signed. |
111 |
+_check_sig_force() { |
112 |
+ debug-print-function ${FUNCNAME} "${@}" |
113 |
+ |
114 |
+ if linux_chkconfig_present MODULE_SIG_FORCE; then |
115 |
+ if use !module-sign; then |
116 |
+ eerror "kernel .config has MODULE_SIG_FORCE=y option set" |
117 |
+ eerror "This means that kernel requires all modules" |
118 |
+ eerror "to be signed and verified before loading" |
119 |
+ eerror "please enable USE=\"module-sign\" or reconfigure your kernel" |
120 |
+ eerror "otherwise loading the module will fail" |
121 |
+ die "signature required" |
122 |
+ fi |
123 |
+ fi |
124 |
+} |
125 |
+ |
126 |
+# @FUNCTION: _sign_module |
127 |
+# @INTERNAL |
128 |
+# @USAGE: <filename> |
129 |
+# @DESCRIPTION: |
130 |
+# Sign a kernel module |
131 |
+_sign_module() { |
132 |
+ debug-print-function ${FUNCNAME} "${@}" |
133 |
+ |
134 |
+ local dotconfig_sig_hash dotconfig_sig_key |
135 |
+ local sign_binary_path sig_key_path sig_x509_path |
136 |
+ local module |
137 |
+ |
138 |
+ # extract values from kernel .config |
139 |
+ # extracted key path is not full, e.g. "certs/signing_key.pem" |
140 |
+ dotconfig_sig_hash="$(linux_chkconfig_string MODULE_SIG_HASH)" |
141 |
+ dotconfig_sig_key="$(linux_chkconfig_string MODULE_SIG_KEY)" |
142 |
+ |
143 |
+ # sign-file binary chokes on double quotes |
144 |
+ dotconfig_sig_hash=${dotconfig_sig_hash//\"/} |
145 |
+ dotconfig_sig_key=${dotconfig_sig_key//\"/} |
146 |
+ |
147 |
+ sign_binary_path="${KV_OUT_DIR}/scripts/sign-file" |
148 |
+ sig_key_path="${KERNEL_MODULE_SIG_KEY:-${KV_OUT_DIR}/${dotconfig_sig_key}}" |
149 |
+ sig_x509_path="${sig_key_path/.pem/.x509}" |
150 |
+ |
151 |
+ module=${1##*/} |
152 |
+ |
153 |
+ # some checks, because sign-file is dumb and produces cryptic errors |
154 |
+ [[ -w "${1}" ]] || die "${1} not found or not writable" |
155 |
+ grep -qFL '~Module signature appended~' "${1}" && die "${module} already signed" |
156 |
+ [[ -x "${sign_binary_path}" ]] || die "${sign_binary_path} not found or not executable" |
157 |
+ [[ -r "${sig_key_path}" ]] || die "Private key ${sig_key_path} not found or not readable" |
158 |
+ [[ -r "${sig_x509_path}" ]] || die "Public key ${sig_x509_path} not found or not readable" |
159 |
+ |
160 |
+ einfo "Signing ${module} using ${sig_key_path}:${dotconfig_sig_hash}" |
161 |
+ "${sign_binary_path}" \ |
162 |
+ "${dotconfig_sig_hash}" "${sig_key_path}" "${sig_x509_path}" \ |
163 |
+ "${1}" || die "Signing ${module} failed" |
164 |
+} |
165 |
+ |
166 |
+# @FUNCTION: _sign_all_modules |
167 |
+# @INTERNAL |
168 |
+# @DESCRIPTION: |
169 |
+# Signs all unsigned modules it finds in installation image |
170 |
+# Called by linux-mod_pkg_preinst |
171 |
+_sign_all_modules() { |
172 |
+ debug-print-function ${FUNCNAME} "${@}" |
173 |
+ |
174 |
+ [[ -z "${KV_OBJ}" ]] && set_kvobj |
175 |
+ require_configured_kernel |
176 |
+ check_kernel_built |
177 |
+ |
178 |
+ local module |
179 |
+ while read -rd '' module; do |
180 |
+ _sign_module "${module}" |
181 |
+ done < <(find "${ED}/lib/modules/${KV_FULL}" -name "*.${KV_OBJ}" -print0) |
182 |
+} |
183 |
+ |
184 |
# internal function |
185 |
# |
186 |
# FUNCTION: |
187 |
@@ -583,12 +678,16 @@ linux-mod_pkg_setup() { |
188 |
# External modules use kernel symbols (bug #591832) |
189 |
CONFIG_CHECK+=" !TRIM_UNUSED_KSYMS" |
190 |
|
191 |
+ # if signature is requested, check if kernel actually supports it |
192 |
+ use module-sign && CONFIG_CHECK+=" MODULE_SIG" |
193 |
+ |
194 |
linux-info_pkg_setup; |
195 |
require_configured_kernel |
196 |
check_kernel_built; |
197 |
strip_modulenames; |
198 |
[[ -n ${MODULE_NAMES} ]] && check_modules_supported |
199 |
set_kvobj; |
200 |
+ _check_sig_force |
201 |
# Commented out with permission from johnm until a fixed version for arches |
202 |
# who intentionally use different kernel and userland compilers can be |
203 |
# introduced - Jason Wever <weeve@g.o>, 23 Oct 2005 |
204 |
@@ -716,8 +815,8 @@ linux-mod_src_install() { |
205 |
|
206 |
einfo "Installing ${modulename} module" |
207 |
cd "${objdir}" || die "${objdir} does not exist" |
208 |
- insinto /lib/modules/${KV_FULL}/${libdir} |
209 |
- doins ${modulename}.${KV_OBJ} || die "doins ${modulename}.${KV_OBJ} failed" |
210 |
+ insinto /lib/modules/"${KV_FULL}/${libdir}" |
211 |
+ doins "${modulename}.${KV_OBJ}" || die "doins ${modulename}.${KV_OBJ} failed" |
212 |
cd "${OLDPWD}" |
213 |
|
214 |
generate_modulesd "${objdir}/${modulename}" |
215 |
@@ -733,6 +832,8 @@ linux-mod_pkg_preinst() { |
216 |
|
217 |
[ -d "${D}lib/modules" ] && UPDATE_DEPMOD=true || UPDATE_DEPMOD=false |
218 |
[ -d "${D}lib/modules" ] && UPDATE_MODULEDB=true || UPDATE_MODULEDB=false |
219 |
+ _check_sig_force |
220 |
+ use module-sign && _sign_all_modules |
221 |
} |
222 |
|
223 |
# @FUNCTION: linux-mod_pkg_postinst |
224 |
diff --git a/profiles/use.desc b/profiles/use.desc |
225 |
index b03b5b9dade..d1da37c45fc 100644 |
226 |
--- a/profiles/use.desc |
227 |
+++ b/profiles/use.desc |
228 |
@@ -207,6 +207,7 @@ mms - Support for Microsoft Media Server (MMS) streams |
229 |
mng - Add support for libmng (MNG images) |
230 |
modplug - Add libmodplug support for playing SoundTracker-style music files |
231 |
modules - Build the kernel modules |
232 |
+module-sign - Sign the kernel modules |
233 |
mono - Build Mono bindings to support dotnet type stuff |
234 |
motif - Add support for the Motif toolkit |
235 |
mozilla - Add support for the Mozilla web-browser |
236 |
-- |
237 |
2.19.0 |