aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@redhat.com>2014-08-08 17:26:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 18:57:32 -0400
commit12db5562e0352986a265841638482b84f3a6899b (patch)
tree533100da8331131037128616b3f9d501c07a6def
parent8fc5b4d4121c95482b2583a07863c6b0aba2d9e1 (diff)
kexec: load and relocate purgatory at kernel load time
Load purgatory code in RAM and relocate it based on the location. Relocation code has been inspired by module relocation code and purgatory relocation code in kexec-tools. Also compute the checksums of loaded kexec segments and store them in purgatory. Arch independent code provides this functionality so that arch dependent bootloaders can make use of it. Helper functions are provided to get/set symbol values in purgatory which are used by bootloaders later to set things like stack and entry point of second kernel etc. Signed-off-by: Vivek Goyal <vgoyal@redhat.com> Cc: Borislav Petkov <bp@suse.de> Cc: Michael Kerrisk <mtk.manpages@gmail.com> Cc: Yinghai Lu <yinghai@kernel.org> Cc: Eric Biederman <ebiederm@xmission.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Matthew Garrett <mjg59@srcf.ucam.org> Cc: Greg Kroah-Hartman <greg@kroah.com> Cc: Dave Young <dyoung@redhat.com> Cc: WANG Chao <chaowang@redhat.com> Cc: Baoquan He <bhe@redhat.com> Cc: Andy Lutomirski <luto@amacapital.net> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/ia64/Kconfig2
-rw-r--r--arch/m68k/Kconfig2
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/powerpc/Kconfig2
-rw-r--r--arch/s390/Kconfig2
-rw-r--r--arch/sh/Kconfig2
-rw-r--r--arch/tile/Kconfig2
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/kernel/machine_kexec_64.c142
-rw-r--r--include/linux/kexec.h33
-rw-r--r--kernel/kexec.c544
12 files changed, 736 insertions, 1 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8e9dbcbcf5af..cacc8d5355b3 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -2065,6 +2065,8 @@ config XIP_PHYS_ADDR
2065config KEXEC 2065config KEXEC
2066 bool "Kexec system call (EXPERIMENTAL)" 2066 bool "Kexec system call (EXPERIMENTAL)"
2067 depends on (!SMP || PM_SLEEP_SMP) 2067 depends on (!SMP || PM_SLEEP_SMP)
2068 select CRYPTO
2069 select CRYPTO_SHA256
2068 help 2070 help
2069 kexec is a system call that implements the ability to shutdown your 2071 kexec is a system call that implements the ability to shutdown your
2070 current kernel, and to start another kernel. It is like a reboot 2072 current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index c84c88bbbbd7..64aefb76bd69 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -549,6 +549,8 @@ source "drivers/sn/Kconfig"
549config KEXEC 549config KEXEC
550 bool "kexec system call" 550 bool "kexec system call"
551 depends on !IA64_HP_SIM && (!SMP || HOTPLUG_CPU) 551 depends on !IA64_HP_SIM && (!SMP || HOTPLUG_CPU)
552 select CRYPTO
553 select CRYPTO_SHA256
552 help 554 help
553 kexec is a system call that implements the ability to shutdown your 555 kexec is a system call that implements the ability to shutdown your
554 current kernel, and to start another kernel. It is like a reboot 556 current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 87b7c7581b1d..3ff8c9a25335 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -91,6 +91,8 @@ config MMU_SUN3
91config KEXEC 91config KEXEC
92 bool "kexec system call" 92 bool "kexec system call"
93 depends on M68KCLASSIC 93 depends on M68KCLASSIC
94 select CRYPTO
95 select CRYPTO_SHA256
94 help 96 help
95 kexec is a system call that implements the ability to shutdown your 97 kexec is a system call that implements the ability to shutdown your
96 current kernel, and to start another kernel. It is like a reboot 98 current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 900c7e5333b6..df51e78a72cc 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -2396,6 +2396,8 @@ source "kernel/Kconfig.preempt"
2396 2396
2397config KEXEC 2397config KEXEC
2398 bool "Kexec system call" 2398 bool "Kexec system call"
2399 select CRYPTO
2400 select CRYPTO_SHA256
2399 help 2401 help
2400 kexec is a system call that implements the ability to shutdown your 2402 kexec is a system call that implements the ability to shutdown your
2401 current kernel, and to start another kernel. It is like a reboot 2403 current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 4bc7b62fb4b6..a577609f8ed6 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -399,6 +399,8 @@ config PPC64_SUPPORTS_MEMORY_FAILURE
399config KEXEC 399config KEXEC
400 bool "kexec system call" 400 bool "kexec system call"
401 depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP)) 401 depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP))
402 select CRYPTO
403 select CRYPTO_SHA256
402 help 404 help
403 kexec is a system call that implements the ability to shutdown your 405 kexec is a system call that implements the ability to shutdown your
404 current kernel, and to start another kernel. It is like a reboot 406 current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 05c78bb5f570..ab39ceb89ecf 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -48,6 +48,8 @@ config ARCH_SUPPORTS_DEBUG_PAGEALLOC
48 48
49config KEXEC 49config KEXEC
50 def_bool y 50 def_bool y
51 select CRYPTO
52 select CRYPTO_SHA256
51 53
52config AUDIT_ARCH 54config AUDIT_ARCH
53 def_bool y 55 def_bool y
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index aa2df3eaeb29..453fa5c09550 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -595,6 +595,8 @@ source kernel/Kconfig.hz
595config KEXEC 595config KEXEC
596 bool "kexec system call (EXPERIMENTAL)" 596 bool "kexec system call (EXPERIMENTAL)"
597 depends on SUPERH32 && MMU 597 depends on SUPERH32 && MMU
598 select CRYPTO
599 select CRYPTO_SHA256
598 help 600 help
599 kexec is a system call that implements the ability to shutdown your 601 kexec is a system call that implements the ability to shutdown your
600 current kernel, and to start another kernel. It is like a reboot 602 current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/tile/Kconfig b/arch/tile/Kconfig
index 7fcd492adbfc..a3ffe2dd4832 100644
--- a/arch/tile/Kconfig
+++ b/arch/tile/Kconfig
@@ -191,6 +191,8 @@ source "kernel/Kconfig.hz"
191 191
192config KEXEC 192config KEXEC
193 bool "kexec system call" 193 bool "kexec system call"
194 select CRYPTO
195 select CRYPTO_SHA256
194 ---help--- 196 ---help---
195 kexec is a system call that implements the ability to shutdown your 197 kexec is a system call that implements the ability to shutdown your
196 current kernel, and to start another kernel. It is like a reboot 198 current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 98fe3df6df82..9558b9fcafbf 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1583,6 +1583,8 @@ source kernel/Kconfig.hz
1583config KEXEC 1583config KEXEC
1584 bool "kexec system call" 1584 bool "kexec system call"
1585 select BUILD_BIN2C 1585 select BUILD_BIN2C
1586 select CRYPTO
1587 select CRYPTO_SHA256
1586 ---help--- 1588 ---help---
1587 kexec is a system call that implements the ability to shutdown your 1589 kexec is a system call that implements the ability to shutdown your
1588 current kernel, and to start another kernel. It is like a reboot 1590 current kernel, and to start another kernel. It is like a reboot
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index c8875b5545e1..88404c440727 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -6,6 +6,8 @@
6 * Version 2. See the file COPYING for more details. 6 * Version 2. See the file COPYING for more details.
7 */ 7 */
8 8
9#define pr_fmt(fmt) "kexec: " fmt
10
9#include <linux/mm.h> 11#include <linux/mm.h>
10#include <linux/kexec.h> 12#include <linux/kexec.h>
11#include <linux/string.h> 13#include <linux/string.h>
@@ -328,3 +330,143 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
328 330
329 return image->fops->cleanup(image); 331 return image->fops->cleanup(image);
330} 332}
333
334/*
335 * Apply purgatory relocations.
336 *
337 * ehdr: Pointer to elf headers
338 * sechdrs: Pointer to section headers.
339 * relsec: section index of SHT_RELA section.
340 *
341 * TODO: Some of the code belongs to generic code. Move that in kexec.c.
342 */
343int arch_kexec_apply_relocations_add(const Elf64_Ehdr *ehdr,
344 Elf64_Shdr *sechdrs, unsigned int relsec)
345{
346 unsigned int i;
347 Elf64_Rela *rel;
348 Elf64_Sym *sym;
349 void *location;
350 Elf64_Shdr *section, *symtabsec;
351 unsigned long address, sec_base, value;
352 const char *strtab, *name, *shstrtab;
353
354 /*
355 * ->sh_offset has been modified to keep the pointer to section
356 * contents in memory
357 */
358 rel = (void *)sechdrs[relsec].sh_offset;
359
360 /* Section to which relocations apply */
361 section = &sechdrs[sechdrs[relsec].sh_info];
362
363 pr_debug("Applying relocate section %u to %u\n", relsec,
364 sechdrs[relsec].sh_info);
365
366 /* Associated symbol table */
367 symtabsec = &sechdrs[sechdrs[relsec].sh_link];
368
369 /* String table */
370 if (symtabsec->sh_link >= ehdr->e_shnum) {
371 /* Invalid strtab section number */
372 pr_err("Invalid string table section index %d\n",
373 symtabsec->sh_link);
374 return -ENOEXEC;
375 }
376
377 strtab = (char *)sechdrs[symtabsec->sh_link].sh_offset;
378
379 /* section header string table */
380 shstrtab = (char *)sechdrs[ehdr->e_shstrndx].sh_offset;
381
382 for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
383
384 /*
385 * rel[i].r_offset contains byte offset from beginning
386 * of section to the storage unit affected.
387 *
388 * This is location to update (->sh_offset). This is temporary
389 * buffer where section is currently loaded. This will finally
390 * be loaded to a different address later, pointed to by
391 * ->sh_addr. kexec takes care of moving it
392 * (kexec_load_segment()).
393 */
394 location = (void *)(section->sh_offset + rel[i].r_offset);
395
396 /* Final address of the location */
397 address = section->sh_addr + rel[i].r_offset;
398
399 /*
400 * rel[i].r_info contains information about symbol table index
401 * w.r.t which relocation must be made and type of relocation
402 * to apply. ELF64_R_SYM() and ELF64_R_TYPE() macros get
403 * these respectively.
404 */
405 sym = (Elf64_Sym *)symtabsec->sh_offset +
406 ELF64_R_SYM(rel[i].r_info);
407
408 if (sym->st_name)
409 name = strtab + sym->st_name;
410 else
411 name = shstrtab + sechdrs[sym->st_shndx].sh_name;
412
413 pr_debug("Symbol: %s info: %02x shndx: %02x value=%llx size: %llx\n",
414 name, sym->st_info, sym->st_shndx, sym->st_value,
415 sym->st_size);
416
417 if (sym->st_shndx == SHN_UNDEF) {
418 pr_err("Undefined symbol: %s\n", name);
419 return -ENOEXEC;
420 }
421
422 if (sym->st_shndx == SHN_COMMON) {
423 pr_err("symbol '%s' in common section\n", name);
424 return -ENOEXEC;
425 }
426
427 if (sym->st_shndx == SHN_ABS)
428 sec_base = 0;
429 else if (sym->st_shndx >= ehdr->e_shnum) {
430 pr_err("Invalid section %d for symbol %s\n",
431 sym->st_shndx, name);
432 return -ENOEXEC;
433 } else
434 sec_base = sechdrs[sym->st_shndx].sh_addr;
435
436 value = sym->st_value;
437 value += sec_base;
438 value += rel[i].r_addend;
439
440 switch (ELF64_R_TYPE(rel[i].r_info)) {
441 case R_X86_64_NONE:
442 break;
443 case R_X86_64_64:
444 *(u64 *)location = value;
445 break;
446 case R_X86_64_32:
447 *(u32 *)location = value;
448 if (value != *(u32 *)location)
449 goto overflow;
450 break;
451 case R_X86_64_32S:
452 *(s32 *)location = value;
453 if ((s64)value != *(s32 *)location)
454 goto overflow;
455 break;
456 case R_X86_64_PC32:
457 value -= (u64)address;
458 *(u32 *)location = value;
459 break;
460 default:
461 pr_err("Unknown rela relocation: %llu\n",
462 ELF64_R_TYPE(rel[i].r_info));
463 return -ENOEXEC;
464 }
465 }
466 return 0;
467
468overflow:
469 pr_err("Overflow in relocation type %d value 0x%lx\n",
470 (int)ELF64_R_TYPE(rel[i].r_info), value);
471 return -ENOEXEC;
472}
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 8e80901e466f..84f09e9eca26 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -10,6 +10,7 @@
10#include <linux/ioport.h> 10#include <linux/ioport.h>
11#include <linux/elfcore.h> 11#include <linux/elfcore.h>
12#include <linux/elf.h> 12#include <linux/elf.h>
13#include <linux/module.h>
13#include <asm/kexec.h> 14#include <asm/kexec.h>
14 15
15/* Verify architecture specific macros are defined */ 16/* Verify architecture specific macros are defined */
@@ -95,6 +96,27 @@ struct compat_kexec_segment {
95}; 96};
96#endif 97#endif
97 98
99struct kexec_sha_region {
100 unsigned long start;
101 unsigned long len;
102};
103
104struct purgatory_info {
105 /* Pointer to elf header of read only purgatory */
106 Elf_Ehdr *ehdr;
107
108 /* Pointer to purgatory sechdrs which are modifiable */
109 Elf_Shdr *sechdrs;
110 /*
111 * Temporary buffer location where purgatory is loaded and relocated
112 * This memory can be freed post image load
113 */
114 void *purgatory_buf;
115
116 /* Address where purgatory is finally loaded and is executed from */
117 unsigned long purgatory_load_addr;
118};
119
98struct kimage { 120struct kimage {
99 kimage_entry_t head; 121 kimage_entry_t head;
100 kimage_entry_t *entry; 122 kimage_entry_t *entry;
@@ -143,6 +165,9 @@ struct kimage {
143 165
144 /* Image loader handling the kernel can store a pointer here */ 166 /* Image loader handling the kernel can store a pointer here */
145 void *image_loader_data; 167 void *image_loader_data;
168
169 /* Information for loading purgatory */
170 struct purgatory_info purgatory_info;
146}; 171};
147 172
148/* 173/*
@@ -189,6 +214,14 @@ extern int kexec_add_buffer(struct kimage *image, char *buffer,
189 unsigned long *load_addr); 214 unsigned long *load_addr);
190extern struct page *kimage_alloc_control_pages(struct kimage *image, 215extern struct page *kimage_alloc_control_pages(struct kimage *image,
191 unsigned int order); 216 unsigned int order);
217extern int kexec_load_purgatory(struct kimage *image, unsigned long min,
218 unsigned long max, int top_down,
219 unsigned long *load_addr);
220extern int kexec_purgatory_get_set_symbol(struct kimage *image,
221 const char *name, void *buf,
222 unsigned int size, bool get_value);
223extern void *kexec_purgatory_get_symbol_addr(struct kimage *image,
224 const char *name);
192extern void crash_kexec(struct pt_regs *); 225extern void crash_kexec(struct pt_regs *);
193int kexec_should_crash(struct task_struct *); 226int kexec_should_crash(struct task_struct *);
194void crash_save_cpu(struct pt_regs *regs, int cpu); 227void crash_save_cpu(struct pt_regs *regs, int cpu);
diff --git a/kernel/kexec.c b/kernel/kexec.c
index 9b46219254dd..669e331aa9ec 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -42,6 +42,9 @@
42#include <asm/io.h> 42#include <asm/io.h>
43#include <asm/sections.h> 43#include <asm/sections.h>
44 44
45#include <crypto/hash.h>
46#include <crypto/sha.h>
47
45/* Per cpu memory for storing cpu states in case of system crash. */ 48/* Per cpu memory for storing cpu states in case of system crash. */
46note_buf_t __percpu *crash_notes; 49note_buf_t __percpu *crash_notes;
47 50
@@ -54,6 +57,15 @@ size_t vmcoreinfo_max_size = sizeof(vmcoreinfo_data);
54/* Flag to indicate we are going to kexec a new kernel */ 57/* Flag to indicate we are going to kexec a new kernel */
55bool kexec_in_progress = false; 58bool kexec_in_progress = false;
56 59
60/*
61 * Declare these symbols weak so that if architecture provides a purgatory,
62 * these will be overridden.
63 */
64char __weak kexec_purgatory[0];
65size_t __weak kexec_purgatory_size = 0;
66
67static int kexec_calculate_store_digests(struct kimage *image);
68
57/* Location of the reserved area for the crash kernel */ 69/* Location of the reserved area for the crash kernel */
58struct resource crashk_res = { 70struct resource crashk_res = {
59 .name = "Crash kernel", 71 .name = "Crash kernel",
@@ -404,6 +416,24 @@ void __weak arch_kimage_file_post_load_cleanup(struct kimage *image)
404{ 416{
405} 417}
406 418
419/* Apply relocations of type RELA */
420int __weak
421arch_kexec_apply_relocations_add(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
422 unsigned int relsec)
423{
424 pr_err("RELA relocation unsupported.\n");
425 return -ENOEXEC;
426}
427
428/* Apply relocations of type REL */
429int __weak
430arch_kexec_apply_relocations(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
431 unsigned int relsec)
432{
433 pr_err("REL relocation unsupported.\n");
434 return -ENOEXEC;
435}
436
407/* 437/*
408 * Free up memory used by kernel, initrd, and comand line. This is temporary 438 * Free up memory used by kernel, initrd, and comand line. This is temporary
409 * memory allocation which is not needed any more after these buffers have 439 * memory allocation which is not needed any more after these buffers have
@@ -411,6 +441,8 @@ void __weak arch_kimage_file_post_load_cleanup(struct kimage *image)
411 */ 441 */
412static void kimage_file_post_load_cleanup(struct kimage *image) 442static void kimage_file_post_load_cleanup(struct kimage *image)
413{ 443{
444 struct purgatory_info *pi = &image->purgatory_info;
445
414 vfree(image->kernel_buf); 446 vfree(image->kernel_buf);
415 image->kernel_buf = NULL; 447 image->kernel_buf = NULL;
416 448
@@ -420,6 +452,12 @@ static void kimage_file_post_load_cleanup(struct kimage *image)
420 kfree(image->cmdline_buf); 452 kfree(image->cmdline_buf);
421 image->cmdline_buf = NULL; 453 image->cmdline_buf = NULL;
422 454
455 vfree(pi->purgatory_buf);
456 pi->purgatory_buf = NULL;
457
458 vfree(pi->sechdrs);
459 pi->sechdrs = NULL;
460
423 /* See if architecture has anything to cleanup post load */ 461 /* See if architecture has anything to cleanup post load */
424 arch_kimage_file_post_load_cleanup(image); 462 arch_kimage_file_post_load_cleanup(image);
425} 463}
@@ -1105,7 +1143,7 @@ static int kimage_load_crash_segment(struct kimage *image,
1105 } 1143 }
1106 ubytes -= uchunk; 1144 ubytes -= uchunk;
1107 maddr += mchunk; 1145 maddr += mchunk;
1108 buf += mchunk; 1146 buf += mchunk;
1109 mbytes -= mchunk; 1147 mbytes -= mchunk;
1110 } 1148 }
1111out: 1149out:
@@ -1340,6 +1378,10 @@ SYSCALL_DEFINE5(kexec_file_load, int, kernel_fd, int, initrd_fd,
1340 if (ret) 1378 if (ret)
1341 goto out; 1379 goto out;
1342 1380
1381 ret = kexec_calculate_store_digests(image);
1382 if (ret)
1383 goto out;
1384
1343 for (i = 0; i < image->nr_segments; i++) { 1385 for (i = 0; i < image->nr_segments; i++) {
1344 struct kexec_segment *ksegment; 1386 struct kexec_segment *ksegment;
1345 1387
@@ -2092,6 +2134,506 @@ int kexec_add_buffer(struct kimage *image, char *buffer, unsigned long bufsz,
2092 return 0; 2134 return 0;
2093} 2135}
2094 2136
2137/* Calculate and store the digest of segments */
2138static int kexec_calculate_store_digests(struct kimage *image)
2139{
2140 struct crypto_shash *tfm;
2141 struct shash_desc *desc;
2142 int ret = 0, i, j, zero_buf_sz, sha_region_sz;
2143 size_t desc_size, nullsz;
2144 char *digest;
2145 void *zero_buf;
2146 struct kexec_sha_region *sha_regions;
2147 struct purgatory_info *pi = &image->purgatory_info;
2148
2149 zero_buf = __va(page_to_pfn(ZERO_PAGE(0)) << PAGE_SHIFT);
2150 zero_buf_sz = PAGE_SIZE;
2151
2152 tfm = crypto_alloc_shash("sha256", 0, 0);
2153 if (IS_ERR(tfm)) {
2154 ret = PTR_ERR(tfm);
2155 goto out;
2156 }
2157
2158 desc_size = crypto_shash_descsize(tfm) + sizeof(*desc);
2159 desc = kzalloc(desc_size, GFP_KERNEL);
2160 if (!desc) {
2161 ret = -ENOMEM;
2162 goto out_free_tfm;
2163 }
2164
2165 sha_region_sz = KEXEC_SEGMENT_MAX * sizeof(struct kexec_sha_region);
2166 sha_regions = vzalloc(sha_region_sz);
2167 if (!sha_regions)
2168 goto out_free_desc;
2169
2170 desc->tfm = tfm;
2171 desc->flags = 0;
2172
2173 ret = crypto_shash_init(desc);
2174 if (ret < 0)
2175 goto out_free_sha_regions;
2176
2177 digest = kzalloc(SHA256_DIGEST_SIZE, GFP_KERNEL);
2178 if (!digest) {
2179 ret = -ENOMEM;
2180 goto out_free_sha_regions;
2181 }
2182
2183 for (j = i = 0; i < image->nr_segments; i++) {
2184 struct kexec_segment *ksegment;
2185
2186 ksegment = &image->segment[i];
2187 /*
2188 * Skip purgatory as it will be modified once we put digest
2189 * info in purgatory.
2190 */
2191 if (ksegment->kbuf == pi->purgatory_buf)
2192 continue;
2193
2194 ret = crypto_shash_update(desc, ksegment->kbuf,
2195 ksegment->bufsz);
2196 if (ret)
2197 break;
2198
2199 /*
2200 * Assume rest of the buffer is filled with zero and
2201 * update digest accordingly.
2202 */
2203 nullsz = ksegment->memsz - ksegment->bufsz;
2204 while (nullsz) {
2205 unsigned long bytes = nullsz;
2206
2207 if (bytes > zero_buf_sz)
2208 bytes = zero_buf_sz;
2209 ret = crypto_shash_update(desc, zero_buf, bytes);
2210 if (ret)
2211 break;
2212 nullsz -= bytes;
2213 }
2214
2215 if (ret)
2216 break;
2217
2218 sha_regions[j].start = ksegment->mem;
2219 sha_regions[j].len = ksegment->memsz;
2220 j++;
2221 }
2222
2223 if (!ret) {
2224 ret = crypto_shash_final(desc, digest);
2225 if (ret)
2226 goto out_free_digest;
2227 ret = kexec_purgatory_get_set_symbol(image, "sha_regions",
2228 sha_regions, sha_region_sz, 0);
2229 if (ret)
2230 goto out_free_digest;
2231
2232 ret = kexec_purgatory_get_set_symbol(image, "sha256_digest",
2233 digest, SHA256_DIGEST_SIZE, 0);
2234 if (ret)
2235 goto out_free_digest;
2236 }
2237
2238out_free_digest:
2239 kfree(digest);
2240out_free_sha_regions:
2241 vfree(sha_regions);
2242out_free_desc:
2243 kfree(desc);
2244out_free_tfm:
2245 kfree(tfm);
2246out:
2247 return ret;
2248}
2249
2250/* Actually load purgatory. Lot of code taken from kexec-tools */
2251static int __kexec_load_purgatory(struct kimage *image, unsigned long min,
2252 unsigned long max, int top_down)
2253{
2254 struct purgatory_info *pi = &image->purgatory_info;
2255 unsigned long align, buf_align, bss_align, buf_sz, bss_sz, bss_pad;
2256 unsigned long memsz, entry, load_addr, curr_load_addr, bss_addr, offset;
2257 unsigned char *buf_addr, *src;
2258 int i, ret = 0, entry_sidx = -1;
2259 const Elf_Shdr *sechdrs_c;
2260 Elf_Shdr *sechdrs = NULL;
2261 void *purgatory_buf = NULL;
2262
2263 /*
2264 * sechdrs_c points to section headers in purgatory and are read
2265 * only. No modifications allowed.
2266 */
2267 sechdrs_c = (void *)pi->ehdr + pi->ehdr->e_shoff;
2268
2269 /*
2270 * We can not modify sechdrs_c[] and its fields. It is read only.
2271 * Copy it over to a local copy where one can store some temporary
2272 * data and free it at the end. We need to modify ->sh_addr and
2273 * ->sh_offset fields to keep track of permanent and temporary
2274 * locations of sections.
2275 */
2276 sechdrs = vzalloc(pi->ehdr->e_shnum * sizeof(Elf_Shdr));
2277 if (!sechdrs)
2278 return -ENOMEM;
2279
2280 memcpy(sechdrs, sechdrs_c, pi->ehdr->e_shnum * sizeof(Elf_Shdr));
2281
2282 /*
2283 * We seem to have multiple copies of sections. First copy is which
2284 * is embedded in kernel in read only section. Some of these sections
2285 * will be copied to a temporary buffer and relocated. And these
2286 * sections will finally be copied to their final destination at
2287 * segment load time.
2288 *
2289 * Use ->sh_offset to reflect section address in memory. It will
2290 * point to original read only copy if section is not allocatable.
2291 * Otherwise it will point to temporary copy which will be relocated.
2292 *
2293 * Use ->sh_addr to contain final address of the section where it
2294 * will go during execution time.
2295 */
2296 for (i = 0; i < pi->ehdr->e_shnum; i++) {
2297 if (sechdrs[i].sh_type == SHT_NOBITS)
2298 continue;
2299
2300 sechdrs[i].sh_offset = (unsigned long)pi->ehdr +
2301 sechdrs[i].sh_offset;
2302 }
2303
2304 /*
2305 * Identify entry point section and make entry relative to section
2306 * start.
2307 */
2308 entry = pi->ehdr->e_entry;
2309 for (i = 0; i < pi->ehdr->e_shnum; i++) {
2310 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
2311 continue;
2312
2313 if (!(sechdrs[i].sh_flags & SHF_EXECINSTR))
2314 continue;
2315
2316 /* Make entry section relative */
2317 if (sechdrs[i].sh_addr <= pi->ehdr->e_entry &&
2318 ((sechdrs[i].sh_addr + sechdrs[i].sh_size) >
2319 pi->ehdr->e_entry)) {
2320 entry_sidx = i;
2321 entry -= sechdrs[i].sh_addr;
2322 break;
2323 }
2324 }
2325
2326 /* Determine how much memory is needed to load relocatable object. */
2327 buf_align = 1;
2328 bss_align = 1;
2329 buf_sz = 0;
2330 bss_sz = 0;
2331
2332 for (i = 0; i < pi->ehdr->e_shnum; i++) {
2333 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
2334 continue;
2335
2336 align = sechdrs[i].sh_addralign;
2337 if (sechdrs[i].sh_type != SHT_NOBITS) {
2338 if (buf_align < align)
2339 buf_align = align;
2340 buf_sz = ALIGN(buf_sz, align);
2341 buf_sz += sechdrs[i].sh_size;
2342 } else {
2343 /* bss section */
2344 if (bss_align < align)
2345 bss_align = align;
2346 bss_sz = ALIGN(bss_sz, align);
2347 bss_sz += sechdrs[i].sh_size;
2348 }
2349 }
2350
2351 /* Determine the bss padding required to align bss properly */
2352 bss_pad = 0;
2353 if (buf_sz & (bss_align - 1))
2354 bss_pad = bss_align - (buf_sz & (bss_align - 1));
2355
2356 memsz = buf_sz + bss_pad + bss_sz;
2357
2358 /* Allocate buffer for purgatory */
2359 purgatory_buf = vzalloc(buf_sz);
2360 if (!purgatory_buf) {
2361 ret = -ENOMEM;
2362 goto out;
2363 }
2364
2365 if (buf_align < bss_align)
2366 buf_align = bss_align;
2367
2368 /* Add buffer to segment list */
2369 ret = kexec_add_buffer(image, purgatory_buf, buf_sz, memsz,
2370 buf_align, min, max, top_down,
2371 &pi->purgatory_load_addr);
2372 if (ret)
2373 goto out;
2374
2375 /* Load SHF_ALLOC sections */
2376 buf_addr = purgatory_buf;
2377 load_addr = curr_load_addr = pi->purgatory_load_addr;
2378 bss_addr = load_addr + buf_sz + bss_pad;
2379
2380 for (i = 0; i < pi->ehdr->e_shnum; i++) {
2381 if (!(sechdrs[i].sh_flags & SHF_ALLOC))
2382 continue;
2383
2384 align = sechdrs[i].sh_addralign;
2385 if (sechdrs[i].sh_type != SHT_NOBITS) {
2386 curr_load_addr = ALIGN(curr_load_addr, align);
2387 offset = curr_load_addr - load_addr;
2388 /* We already modifed ->sh_offset to keep src addr */
2389 src = (char *) sechdrs[i].sh_offset;
2390 memcpy(buf_addr + offset, src, sechdrs[i].sh_size);
2391
2392 /* Store load address and source address of section */
2393 sechdrs[i].sh_addr = curr_load_addr;
2394
2395 /*
2396 * This section got copied to temporary buffer. Update
2397 * ->sh_offset accordingly.
2398 */
2399 sechdrs[i].sh_offset = (unsigned long)(buf_addr + offset);
2400
2401 /* Advance to the next address */
2402 curr_load_addr += sechdrs[i].sh_size;
2403 } else {
2404 bss_addr = ALIGN(bss_addr, align);
2405 sechdrs[i].sh_addr = bss_addr;
2406 bss_addr += sechdrs[i].sh_size;
2407 }
2408 }
2409
2410 /* Update entry point based on load address of text section */
2411 if (entry_sidx >= 0)
2412 entry += sechdrs[entry_sidx].sh_addr;
2413
2414 /* Make kernel jump to purgatory after shutdown */
2415 image->start = entry;
2416
2417 /* Used later to get/set symbol values */
2418 pi->sechdrs = sechdrs;
2419
2420 /*
2421 * Used later to identify which section is purgatory and skip it
2422 * from checksumming.
2423 */
2424 pi->purgatory_buf = purgatory_buf;
2425 return ret;
2426out:
2427 vfree(sechdrs);
2428 vfree(purgatory_buf);
2429 return ret;
2430}
2431
2432static int kexec_apply_relocations(struct kimage *image)
2433{
2434 int i, ret;
2435 struct purgatory_info *pi = &image->purgatory_info;
2436 Elf_Shdr *sechdrs = pi->sechdrs;
2437
2438 /* Apply relocations */
2439 for (i = 0; i < pi->ehdr->e_shnum; i++) {
2440 Elf_Shdr *section, *symtab;
2441
2442 if (sechdrs[i].sh_type != SHT_RELA &&
2443 sechdrs[i].sh_type != SHT_REL)
2444 continue;
2445
2446 /*
2447 * For section of type SHT_RELA/SHT_REL,
2448 * ->sh_link contains section header index of associated
2449 * symbol table. And ->sh_info contains section header
2450 * index of section to which relocations apply.
2451 */
2452 if (sechdrs[i].sh_info >= pi->ehdr->e_shnum ||
2453 sechdrs[i].sh_link >= pi->ehdr->e_shnum)
2454 return -ENOEXEC;
2455
2456 section = &sechdrs[sechdrs[i].sh_info];
2457 symtab = &sechdrs[sechdrs[i].sh_link];
2458
2459 if (!(section->sh_flags & SHF_ALLOC))
2460 continue;
2461
2462 /*
2463 * symtab->sh_link contain section header index of associated
2464 * string table.
2465 */
2466 if (symtab->sh_link >= pi->ehdr->e_shnum)
2467 /* Invalid section number? */
2468 continue;
2469
2470 /*
2471 * Respective archicture needs to provide support for applying
2472 * relocations of type SHT_RELA/SHT_REL.
2473 */
2474 if (sechdrs[i].sh_type == SHT_RELA)
2475 ret = arch_kexec_apply_relocations_add(pi->ehdr,
2476 sechdrs, i);
2477 else if (sechdrs[i].sh_type == SHT_REL)
2478 ret = arch_kexec_apply_relocations(pi->ehdr,
2479 sechdrs, i);
2480 if (ret)
2481 return ret;
2482 }
2483
2484 return 0;
2485}
2486
2487/* Load relocatable purgatory object and relocate it appropriately */
2488int kexec_load_purgatory(struct kimage *image, unsigned long min,
2489 unsigned long max, int top_down,
2490 unsigned long *load_addr)
2491{
2492 struct purgatory_info *pi = &image->purgatory_info;
2493 int ret;
2494
2495 if (kexec_purgatory_size <= 0)
2496 return -EINVAL;
2497
2498 if (kexec_purgatory_size < sizeof(Elf_Ehdr))
2499 return -ENOEXEC;
2500
2501 pi->ehdr = (Elf_Ehdr *)kexec_purgatory;
2502
2503 if (memcmp(pi->ehdr->e_ident, ELFMAG, SELFMAG) != 0
2504 || pi->ehdr->e_type != ET_REL
2505 || !elf_check_arch(pi->ehdr)
2506 || pi->ehdr->e_shentsize != sizeof(Elf_Shdr))
2507 return -ENOEXEC;
2508
2509 if (pi->ehdr->e_shoff >= kexec_purgatory_size
2510 || (pi->ehdr->e_shnum * sizeof(Elf_Shdr) >
2511 kexec_purgatory_size - pi->ehdr->e_shoff))
2512 return -ENOEXEC;
2513
2514 ret = __kexec_load_purgatory(image, min, max, top_down);
2515 if (ret)
2516 return ret;
2517
2518 ret = kexec_apply_relocations(image);
2519 if (ret)
2520 goto out;
2521
2522 *load_addr = pi->purgatory_load_addr;
2523 return 0;
2524out:
2525 vfree(pi->sechdrs);
2526 vfree(pi->purgatory_buf);
2527 return ret;
2528}
2529
2530static Elf_Sym *kexec_purgatory_find_symbol(struct purgatory_info *pi,
2531 const char *name)
2532{
2533 Elf_Sym *syms;
2534 Elf_Shdr *sechdrs;
2535 Elf_Ehdr *ehdr;
2536 int i, k;
2537 const char *strtab;
2538
2539 if (!pi->sechdrs || !pi->ehdr)
2540 return NULL;
2541
2542 sechdrs = pi->sechdrs;
2543 ehdr = pi->ehdr;
2544
2545 for (i = 0; i < ehdr->e_shnum; i++) {
2546 if (sechdrs[i].sh_type != SHT_SYMTAB)
2547 continue;
2548
2549 if (sechdrs[i].sh_link >= ehdr->e_shnum)
2550 /* Invalid strtab section number */
2551 continue;
2552 strtab = (char *)sechdrs[sechdrs[i].sh_link].sh_offset;
2553 syms = (Elf_Sym *)sechdrs[i].sh_offset;
2554
2555 /* Go through symbols for a match */
2556 for (k = 0; k < sechdrs[i].sh_size/sizeof(Elf_Sym); k++) {
2557 if (ELF_ST_BIND(syms[k].st_info) != STB_GLOBAL)
2558 continue;
2559
2560 if (strcmp(strtab + syms[k].st_name, name) != 0)
2561 continue;
2562
2563 if (syms[k].st_shndx == SHN_UNDEF ||
2564 syms[k].st_shndx >= ehdr->e_shnum) {
2565 pr_debug("Symbol: %s has bad section index %d.\n",
2566 name, syms[k].st_shndx);
2567 return NULL;
2568 }
2569
2570 /* Found the symbol we are looking for */
2571 return &syms[k];
2572 }
2573 }
2574
2575 return NULL;
2576}
2577
2578void *kexec_purgatory_get_symbol_addr(struct kimage *image, const char *name)
2579{
2580 struct purgatory_info *pi = &image->purgatory_info;
2581 Elf_Sym *sym;
2582 Elf_Shdr *sechdr;
2583
2584 sym = kexec_purgatory_find_symbol(pi, name);
2585 if (!sym)
2586 return ERR_PTR(-EINVAL);
2587
2588 sechdr = &pi->sechdrs[sym->st_shndx];
2589
2590 /*
2591 * Returns the address where symbol will finally be loaded after
2592 * kexec_load_segment()
2593 */
2594 return (void *)(sechdr->sh_addr + sym->st_value);
2595}
2596
2597/*
2598 * Get or set value of a symbol. If "get_value" is true, symbol value is
2599 * returned in buf otherwise symbol value is set based on value in buf.
2600 */
2601int kexec_purgatory_get_set_symbol(struct kimage *image, const char *name,
2602 void *buf, unsigned int size, bool get_value)
2603{
2604 Elf_Sym *sym;
2605 Elf_Shdr *sechdrs;
2606 struct purgatory_info *pi = &image->purgatory_info;
2607 char *sym_buf;
2608
2609 sym = kexec_purgatory_find_symbol(pi, name);
2610 if (!sym)
2611 return -EINVAL;
2612
2613 if (sym->st_size != size) {
2614 pr_err("symbol %s size mismatch: expected %lu actual %u\n",
2615 name, (unsigned long)sym->st_size, size);
2616 return -EINVAL;
2617 }
2618
2619 sechdrs = pi->sechdrs;
2620
2621 if (sechdrs[sym->st_shndx].sh_type == SHT_NOBITS) {
2622 pr_err("symbol %s is in a bss section. Cannot %s\n", name,
2623 get_value ? "get" : "set");
2624 return -EINVAL;
2625 }
2626
2627 sym_buf = (unsigned char *)sechdrs[sym->st_shndx].sh_offset +
2628 sym->st_value;
2629
2630 if (get_value)
2631 memcpy((void *)buf, sym_buf, size);
2632 else
2633 memcpy((void *)sym_buf, buf, size);
2634
2635 return 0;
2636}
2095 2637
2096/* 2638/*
2097 * Move into place and start executing a preloaded standalone 2639 * Move into place and start executing a preloaded standalone