aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVivek Goyal <vgoyal@redhat.com>2014-08-08 17:26:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-08 18:57:33 -0400
commit8e7d838103feac320baf9e68d73f954840ac1eea (patch)
treec9426b2a0b83962a08d0cf48001594e4b8e59541
parent6a2c20e7d8900ed273dc34a9af9bf02fc478e427 (diff)
kexec: verify the signature of signed PE bzImage
This is the final piece of the puzzle of verifying kernel image signature during kexec_file_load() syscall. This patch calls into PE file routines to verify signature of bzImage. If signature are valid, kexec_file_load() succeeds otherwise it fails. Two new config options have been introduced. First one is CONFIG_KEXEC_VERIFY_SIG. This option enforces that kernel has to be validly signed otherwise kernel load will fail. If this option is not set, no signature verification will be done. Only exception will be when secureboot is enabled. In that case signature verification should be automatically enforced when secureboot is enabled. But that will happen when secureboot patches are merged. Second config option is CONFIG_KEXEC_BZIMAGE_VERIFY_SIG. This option enables signature verification support on bzImage. If this option is not set and previous one is set, kernel image loading will fail because kernel does not have support to verify signature of bzImage. I tested these patches with both "pesign" and "sbsign" signed bzImages. I used signing_key.priv key and signing_key.x509 cert for signing as generated during kernel build process (if module signing is enabled). Used following method to sign bzImage. pesign ====== - Convert DER format cert to PEM format cert openssl x509 -in signing_key.x509 -inform DER -out signing_key.x509.PEM -outform PEM - Generate a .p12 file from existing cert and private key file openssl pkcs12 -export -out kernel-key.p12 -inkey signing_key.priv -in signing_key.x509.PEM - Import .p12 file into pesign db pk12util -i /tmp/kernel-key.p12 -d /etc/pki/pesign - Sign bzImage pesign -i /boot/vmlinuz-3.16.0-rc3+ -o /boot/vmlinuz-3.16.0-rc3+.signed.pesign -c "Glacier signing key - Magrathea" -s sbsign ====== sbsign --key signing_key.priv --cert signing_key.x509.PEM --output /boot/vmlinuz-3.16.0-rc3+.signed.sbsign /boot/vmlinuz-3.16.0-rc3+ Patch details: Well all the hard work is done in previous patches. Now bzImage loader has just call into that code and verify whether bzImage signature are valid or not. Also create two config options. First one is CONFIG_KEXEC_VERIFY_SIG. This option enforces that kernel has to be validly signed otherwise kernel load will fail. If this option is not set, no signature verification will be done. Only exception will be when secureboot is enabled. In that case signature verification should be automatically enforced when secureboot is enabled. But that will happen when secureboot patches are merged. Second config option is CONFIG_KEXEC_BZIMAGE_VERIFY_SIG. This option enables signature verification support on bzImage. If this option is not set and previous one is set, kernel image loading will fail because kernel does not have support to verify signature of bzImage. 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> Cc: Matt Fleming <matt@console-pimps.org> Cc: David Howells <dhowells@redhat.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/x86/Kconfig22
-rw-r--r--arch/x86/kernel/kexec-bzimage64.c21
-rw-r--r--arch/x86/kernel/machine_kexec_64.c11
-rw-r--r--include/linux/kexec.h3
-rw-r--r--kernel/kexec.c15
5 files changed, 72 insertions, 0 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 9558b9fcafbf..4aafd322e21e 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -1599,6 +1599,28 @@ config KEXEC
1599 interface is strongly in flux, so no good recommendation can be 1599 interface is strongly in flux, so no good recommendation can be
1600 made. 1600 made.
1601 1601
1602config KEXEC_VERIFY_SIG
1603 bool "Verify kernel signature during kexec_file_load() syscall"
1604 depends on KEXEC
1605 ---help---
1606 This option makes kernel signature verification mandatory for
1607 kexec_file_load() syscall. If kernel is signature can not be
1608 verified, kexec_file_load() will fail.
1609
1610 This option enforces signature verification at generic level.
1611 One needs to enable signature verification for type of kernel
1612 image being loaded to make sure it works. For example, enable
1613 bzImage signature verification option to be able to load and
1614 verify signatures of bzImage. Otherwise kernel loading will fail.
1615
1616config KEXEC_BZIMAGE_VERIFY_SIG
1617 bool "Enable bzImage signature verification support"
1618 depends on KEXEC_VERIFY_SIG
1619 depends on SIGNED_PE_FILE_VERIFICATION
1620 select SYSTEM_TRUSTED_KEYRING
1621 ---help---
1622 Enable bzImage signature verification support.
1623
1602config CRASH_DUMP 1624config CRASH_DUMP
1603 bool "kernel crash dumps" 1625 bool "kernel crash dumps"
1604 depends on X86_64 || (X86_32 && HIGHMEM) 1626 depends on X86_64 || (X86_32 && HIGHMEM)
diff --git a/arch/x86/kernel/kexec-bzimage64.c b/arch/x86/kernel/kexec-bzimage64.c
index 623e6c58081f..9642b9b33655 100644
--- a/arch/x86/kernel/kexec-bzimage64.c
+++ b/arch/x86/kernel/kexec-bzimage64.c
@@ -19,6 +19,8 @@
19#include <linux/kernel.h> 19#include <linux/kernel.h>
20#include <linux/mm.h> 20#include <linux/mm.h>
21#include <linux/efi.h> 21#include <linux/efi.h>
22#include <linux/verify_pefile.h>
23#include <keys/system_keyring.h>
22 24
23#include <asm/bootparam.h> 25#include <asm/bootparam.h>
24#include <asm/setup.h> 26#include <asm/setup.h>
@@ -525,8 +527,27 @@ int bzImage64_cleanup(void *loader_data)
525 return 0; 527 return 0;
526} 528}
527 529
530#ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG
531int bzImage64_verify_sig(const char *kernel, unsigned long kernel_len)
532{
533 bool trusted;
534 int ret;
535
536 ret = verify_pefile_signature(kernel, kernel_len,
537 system_trusted_keyring, &trusted);
538 if (ret < 0)
539 return ret;
540 if (!trusted)
541 return -EKEYREJECTED;
542 return 0;
543}
544#endif
545
528struct kexec_file_ops kexec_bzImage64_ops = { 546struct kexec_file_ops kexec_bzImage64_ops = {
529 .probe = bzImage64_probe, 547 .probe = bzImage64_probe,
530 .load = bzImage64_load, 548 .load = bzImage64_load,
531 .cleanup = bzImage64_cleanup, 549 .cleanup = bzImage64_cleanup,
550#ifdef CONFIG_KEXEC_BZIMAGE_VERIFY_SIG
551 .verify_sig = bzImage64_verify_sig,
552#endif
532}; 553};
diff --git a/arch/x86/kernel/machine_kexec_64.c b/arch/x86/kernel/machine_kexec_64.c
index 9330434da777..8b04018e5d1f 100644
--- a/arch/x86/kernel/machine_kexec_64.c
+++ b/arch/x86/kernel/machine_kexec_64.c
@@ -372,6 +372,17 @@ int arch_kimage_file_post_load_cleanup(struct kimage *image)
372 return image->fops->cleanup(image->image_loader_data); 372 return image->fops->cleanup(image->image_loader_data);
373} 373}
374 374
375int arch_kexec_kernel_verify_sig(struct kimage *image, void *kernel,
376 unsigned long kernel_len)
377{
378 if (!image->fops || !image->fops->verify_sig) {
379 pr_debug("kernel loader does not support signature verification.");
380 return -EKEYREJECTED;
381 }
382
383 return image->fops->verify_sig(kernel, kernel_len);
384}
385
375/* 386/*
376 * Apply purgatory relocations. 387 * Apply purgatory relocations.
377 * 388 *
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index 9481703b0e7a..4b2a0e11cc5b 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -191,11 +191,14 @@ typedef void *(kexec_load_t)(struct kimage *image, char *kernel_buf,
191 unsigned long initrd_len, char *cmdline, 191 unsigned long initrd_len, char *cmdline,
192 unsigned long cmdline_len); 192 unsigned long cmdline_len);
193typedef int (kexec_cleanup_t)(void *loader_data); 193typedef int (kexec_cleanup_t)(void *loader_data);
194typedef int (kexec_verify_sig_t)(const char *kernel_buf,
195 unsigned long kernel_len);
194 196
195struct kexec_file_ops { 197struct kexec_file_ops {
196 kexec_probe_t *probe; 198 kexec_probe_t *probe;
197 kexec_load_t *load; 199 kexec_load_t *load;
198 kexec_cleanup_t *cleanup; 200 kexec_cleanup_t *cleanup;
201 kexec_verify_sig_t *verify_sig;
199}; 202};
200 203
201/* kexec interface functions */ 204/* kexec interface functions */
diff --git a/kernel/kexec.c b/kernel/kexec.c
index f18c780f9716..0b49a0a58102 100644
--- a/kernel/kexec.c
+++ b/kernel/kexec.c
@@ -416,6 +416,12 @@ void __weak arch_kimage_file_post_load_cleanup(struct kimage *image)
416{ 416{
417} 417}
418 418
419int __weak arch_kexec_kernel_verify_sig(struct kimage *image, void *buf,
420 unsigned long buf_len)
421{
422 return -EKEYREJECTED;
423}
424
419/* Apply relocations of type RELA */ 425/* Apply relocations of type RELA */
420int __weak 426int __weak
421arch_kexec_apply_relocations_add(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, 427arch_kexec_apply_relocations_add(const Elf_Ehdr *ehdr, Elf_Shdr *sechdrs,
@@ -494,6 +500,15 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
494 if (ret) 500 if (ret)
495 goto out; 501 goto out;
496 502
503#ifdef CONFIG_KEXEC_VERIFY_SIG
504 ret = arch_kexec_kernel_verify_sig(image, image->kernel_buf,
505 image->kernel_buf_len);
506 if (ret) {
507 pr_debug("kernel signature verification failed.\n");
508 goto out;
509 }
510 pr_debug("kernel signature verification successful.\n");
511#endif
497 /* It is possible that there no initramfs is being loaded */ 512 /* It is possible that there no initramfs is being loaded */
498 if (!(flags & KEXEC_FILE_NO_INITRAMFS)) { 513 if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
499 ret = copy_file_from_fd(initrd_fd, &image->initrd_buf, 514 ret = copy_file_from_fd(initrd_fd, &image->initrd_buf,