aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/kexec.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/kexec.c')
-rw-r--r--kernel/kexec.c544
1 files changed, 543 insertions, 1 deletions
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