Skip to content

Commit 4b97cec

Browse files
Xunlei PangAlex Shi
authored andcommitted
kexec: introduce a protection mechanism for the crashkernel reserved memory
For the cases that some kernel (module) path stamps the crash reserved memory(already mapped by the kernel) where has been loaded the second kernel data, the kdump kernel will probably fail to boot when panic happens (or even not happens) leaving the culprit at large, this is unacceptable. The patch introduces a mechanism for detecting such cases: 1) After each crash kexec loading, it simply marks the reserved memory regions readonly since we no longer access it after that. When someone stamps the region, the first kernel will panic and trigger the kdump. The weak arch_kexec_protect_crashkres() is introduced to do the actual protection. 2) To allow multiple loading, once 1) was done we also need to remark the reserved memory to readwrite each time a system call related to kdump is made. The weak arch_kexec_unprotect_crashkres() is introduced to do the actual protection. The architecture can make its specific implementation by overriding arch_kexec_protect_crashkres() and arch_kexec_unprotect_crashkres(). Signed-off-by: Xunlei Pang <xlpang@redhat.com> Cc: Eric Biederman <ebiederm@xmission.com> Cc: Dave Young <dyoung@redhat.com> Cc: Minfei Huang <mhuang@redhat.com> Cc: Vivek Goyal <vgoyal@redhat.com> Cc: Baoquan He <bhe@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> (cherry picked from commit 9b492cf58077a0254eb4b9574029ac6e79add9f9) Signed-off-by: Alex Shi <alex.shi@linaro.org>
1 parent 8db423d commit 4b97cec

4 files changed

Lines changed: 23 additions & 2 deletions

File tree

include/linux/kexec.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ int __weak arch_kexec_apply_relocations_add(const Elf_Ehdr *ehdr,
328328
Elf_Shdr *sechdrs, unsigned int relsec);
329329
int __weak arch_kexec_apply_relocations(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
330330
unsigned int relsec);
331+
void arch_kexec_protect_crashkres(void);
332+
void arch_kexec_unprotect_crashkres(void);
331333

332334
#else /* !CONFIG_KEXEC_CORE */
333335
struct pt_regs;

kernel/kexec.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,8 +167,12 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
167167
return -EBUSY;
168168

169169
dest_image = &kexec_image;
170-
if (flags & KEXEC_ON_CRASH)
170+
if (flags & KEXEC_ON_CRASH) {
171171
dest_image = &kexec_crash_image;
172+
if (kexec_crash_image)
173+
arch_kexec_unprotect_crashkres();
174+
}
175+
172176
if (nr_segments > 0) {
173177
unsigned long i;
174178

@@ -211,6 +215,9 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments,
211215
image = xchg(dest_image, image);
212216

213217
out:
218+
if ((flags & KEXEC_ON_CRASH) && kexec_crash_image)
219+
arch_kexec_protect_crashkres();
220+
214221
mutex_unlock(&kexec_mutex);
215222
kimage_free(image);
216223

kernel/kexec_core.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,3 +1532,9 @@ void __weak crash_map_reserved_pages(void)
15321532

15331533
void __weak crash_unmap_reserved_pages(void)
15341534
{}
1535+
1536+
void __weak arch_kexec_protect_crashkres(void)
1537+
{}
1538+
1539+
void __weak arch_kexec_unprotect_crashkres(void)
1540+
{}

kernel/kexec_file.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,11 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
327327
return -EBUSY;
328328

329329
dest_image = &kexec_image;
330-
if (flags & KEXEC_FILE_ON_CRASH)
330+
if (flags & KEXEC_FILE_ON_CRASH) {
331331
dest_image = &kexec_crash_image;
332+
if (kexec_crash_image)
333+
arch_kexec_unprotect_crashkres();
334+
}
332335

333336
if (flags & KEXEC_FILE_UNLOAD)
334337
goto exchange;
@@ -377,6 +380,9 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
377380
exchange:
378381
image = xchg(dest_image, image);
379382
out:
383+
if ((flags & KEXEC_FILE_ON_CRASH) && kexec_crash_image)
384+
arch_kexec_protect_crashkres();
385+
380386
mutex_unlock(&kexec_mutex);
381387
kimage_free(image);
382388
return ret;

0 commit comments

Comments
 (0)