hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/kernel/kexec.c
....@@ -1,9 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * kexec.c - kexec_load system call
34 * Copyright (C) 2002-2004 Eric Biederman <ebiederm@xmission.com>
4
- *
5
- * This source code is licensed under the GNU General Public License,
6
- * Version 2. See the file COPYING for more details.
75 */
86
97 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
....@@ -112,6 +110,14 @@
112110 unsigned long i;
113111 int ret;
114112
113
+ /*
114
+ * Because we write directly to the reserved memory region when loading
115
+ * crash kernels we need a serialization here to prevent multiple crash
116
+ * kernels from attempting to load simultaneously.
117
+ */
118
+ if (!kexec_trylock())
119
+ return -EBUSY;
120
+
115121 if (flags & KEXEC_ON_CRASH) {
116122 dest_image = &kexec_crash_image;
117123 if (kexec_crash_image)
....@@ -123,7 +129,8 @@
123129 if (nr_segments == 0) {
124130 /* Uninstall image */
125131 kimage_free(xchg(dest_image, NULL));
126
- return 0;
132
+ ret = 0;
133
+ goto out_unlock;
127134 }
128135 if (flags & KEXEC_ON_CRASH) {
129136 /*
....@@ -136,7 +143,7 @@
136143
137144 ret = kimage_alloc_init(&image, entry, nr_segments, segments, flags);
138145 if (ret)
139
- return ret;
146
+ goto out_unlock;
140147
141148 if (flags & KEXEC_PRESERVE_CONTEXT)
142149 image->preserve_context = 1;
....@@ -161,6 +168,10 @@
161168
162169 kimage_terminate(image);
163170
171
+ ret = machine_kexec_post_load(image);
172
+ if (ret)
173
+ goto out;
174
+
164175 /* Install the new kernel and uninstall the old */
165176 image = xchg(dest_image, image);
166177
....@@ -169,6 +180,8 @@
169180 arch_kexec_protect_crashkres();
170181
171182 kimage_free(image);
183
+out_unlock:
184
+ kexec_unlock();
172185 return ret;
173186 }
174187
....@@ -203,8 +216,16 @@
203216 return -EPERM;
204217
205218 /* Permit LSMs and IMA to fail the kexec */
206
- result = security_kernel_load_data(LOADING_KEXEC_IMAGE);
219
+ result = security_kernel_load_data(LOADING_KEXEC_IMAGE, false);
207220 if (result < 0)
221
+ return result;
222
+
223
+ /*
224
+ * kexec can be used to circumvent module loading restrictions, so
225
+ * prevent loading in that case
226
+ */
227
+ result = security_locked_down(LOCKDOWN_KEXEC);
228
+ if (result)
208229 return result;
209230
210231 /*
....@@ -237,20 +258,7 @@
237258 ((flags & KEXEC_ARCH_MASK) != KEXEC_ARCH_DEFAULT))
238259 return -EINVAL;
239260
240
- /* Because we write directly to the reserved memory
241
- * region when loading crash kernels we need a mutex here to
242
- * prevent multiple crash kernels from attempting to load
243
- * simultaneously, and to prevent a crash kernel from loading
244
- * over the top of a in use crash kernel.
245
- *
246
- * KISS: always take the mutex.
247
- */
248
- if (!mutex_trylock(&kexec_mutex))
249
- return -EBUSY;
250
-
251261 result = do_kexec_load(entry, nr_segments, segments, flags);
252
-
253
- mutex_unlock(&kexec_mutex);
254262
255263 return result;
256264 }
....@@ -291,20 +299,7 @@
291299 return -EFAULT;
292300 }
293301
294
- /* Because we write directly to the reserved memory
295
- * region when loading crash kernels we need a mutex here to
296
- * prevent multiple crash kernels from attempting to load
297
- * simultaneously, and to prevent a crash kernel from loading
298
- * over the top of a in use crash kernel.
299
- *
300
- * KISS: always take the mutex.
301
- */
302
- if (!mutex_trylock(&kexec_mutex))
303
- return -EBUSY;
304
-
305302 result = do_kexec_load(entry, nr_segments, ksegments, flags);
306
-
307
- mutex_unlock(&kexec_mutex);
308303
309304 return result;
310305 }