From: Matthew Garrett <matthewgarrett@google.com> To: jmorris@namei.org Cc: linux-security-module@vger.kernel.org, linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, Jiri Bohac <jbohac@suse.cz>, David Howells <dhowells@redhat.com>, Matthew Garrett <mjg59@google.com>, Dave Young <dyoung@redhat.com>, kexec@lists.infradead.org Subject: [PATCH V37 08/29] kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE Date: Wed, 31 Jul 2019 15:15:56 -0700 [thread overview] Message-ID: <20190731221617.234725-9-matthewgarrett@google.com> (raw) In-Reply-To: <20190731221617.234725-1-matthewgarrett@google.com> From: Jiri Bohac <jbohac@suse.cz> This is a preparatory patch for kexec_file_load() lockdown. A locked down kernel needs to prevent unsigned kernel images from being loaded with kexec_file_load(). Currently, the only way to force the signature verification is compiling with KEXEC_VERIFY_SIG. This prevents loading usigned images even when the kernel is not locked down at runtime. This patch splits KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE. Analogous to the MODULE_SIG and MODULE_SIG_FORCE for modules, KEXEC_SIG turns on the signature verification but allows unsigned images to be loaded. KEXEC_SIG_FORCE disallows images without a valid signature. Signed-off-by: Jiri Bohac <jbohac@suse.cz> Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Matthew Garrett <mjg59@google.com> Reviewed-by: Jiri Bohac <jbohac@suse.cz> Reviewed-by: Dave Young <dyoung@redhat.com> cc: kexec@lists.infradead.org --- arch/x86/Kconfig | 20 +++++++++---- crypto/asymmetric_keys/verify_pefile.c | 4 ++- include/linux/kexec.h | 4 +-- kernel/kexec_file.c | 41 ++++++++++++++++++++++---- 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 05e78acb187c..fd2cd4f861cc 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2032,20 +2032,30 @@ config KEXEC_FILE config ARCH_HAS_KEXEC_PURGATORY def_bool KEXEC_FILE -config KEXEC_VERIFY_SIG +config KEXEC_SIG bool "Verify kernel signature during kexec_file_load() syscall" depends on KEXEC_FILE ---help--- - This option makes kernel signature verification mandatory for - the kexec_file_load() syscall. - In addition to that option, you need to enable signature + This option makes the kexec_file_load() syscall check for a valid + signature of the kernel image. The image can still be loaded without + a valid signature unless you also enable KEXEC_SIG_FORCE, though if + there's a signature that we can check, then it must be valid. + + In addition to this option, you need to enable signature verification for the corresponding kernel image type being loaded in order for this to work. +config KEXEC_SIG_FORCE + bool "Require a valid signature in kexec_file_load() syscall" + depends on KEXEC_SIG + ---help--- + This option makes kernel signature verification mandatory for + the kexec_file_load() syscall. + config KEXEC_BZIMAGE_VERIFY_SIG bool "Enable bzImage signature verification support" - depends on KEXEC_VERIFY_SIG + depends on KEXEC_SIG depends on SIGNED_PE_FILE_VERIFICATION select SYSTEM_TRUSTED_KEYRING ---help--- diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c index 3b303fe2f061..cc9dbcecaaca 100644 --- a/crypto/asymmetric_keys/verify_pefile.c +++ b/crypto/asymmetric_keys/verify_pefile.c @@ -96,7 +96,7 @@ static int pefile_parse_binary(const void *pebuf, unsigned int pelen, if (!ddir->certs.virtual_address || !ddir->certs.size) { pr_debug("Unsigned PE binary\n"); - return -EKEYREJECTED; + return -ENODATA; } chkaddr(ctx->header_size, ddir->certs.virtual_address, @@ -403,6 +403,8 @@ static int pefile_digest_pe(const void *pebuf, unsigned int pelen, * (*) 0 if at least one signature chain intersects with the keys in the trust * keyring, or: * + * (*) -ENODATA if there is no signature present. + * * (*) -ENOPKG if a suitable crypto module couldn't be found for a check on a * chain. * diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 305f6a5ca4fe..998f77c3a0e1 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -125,7 +125,7 @@ typedef void *(kexec_load_t)(struct kimage *image, char *kernel_buf, unsigned long cmdline_len); typedef int (kexec_cleanup_t)(void *loader_data); -#ifdef CONFIG_KEXEC_VERIFY_SIG +#ifdef CONFIG_KEXEC_SIG typedef int (kexec_verify_sig_t)(const char *kernel_buf, unsigned long kernel_len); #endif @@ -134,7 +134,7 @@ struct kexec_file_ops { kexec_probe_t *probe; kexec_load_t *load; kexec_cleanup_t *cleanup; -#ifdef CONFIG_KEXEC_VERIFY_SIG +#ifdef CONFIG_KEXEC_SIG kexec_verify_sig_t *verify_sig; #endif }; diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index b8cc032d5620..875482c34154 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -88,7 +88,7 @@ int __weak arch_kimage_file_post_load_cleanup(struct kimage *image) return kexec_image_post_load_cleanup_default(image); } -#ifdef CONFIG_KEXEC_VERIFY_SIG +#ifdef CONFIG_KEXEC_SIG static int kexec_image_verify_sig_default(struct kimage *image, void *buf, unsigned long buf_len) { @@ -186,7 +186,8 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd, const char __user *cmdline_ptr, unsigned long cmdline_len, unsigned flags) { - int ret = 0; + const char *reason; + int ret; void *ldata; loff_t size; @@ -202,14 +203,42 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd, if (ret) goto out; -#ifdef CONFIG_KEXEC_VERIFY_SIG +#ifdef CONFIG_KEXEC_SIG ret = arch_kexec_kernel_verify_sig(image, image->kernel_buf, image->kernel_buf_len); - if (ret) { - pr_debug("kernel signature verification failed.\n"); + switch (ret) { + case 0: + break; + + /* Certain verification errors are non-fatal if we're not + * checking errors, provided we aren't mandating that there + * must be a valid signature. + */ + case -ENODATA: + reason = "kexec of unsigned image"; + goto decide; + case -ENOPKG: + reason = "kexec of image with unsupported crypto"; + goto decide; + case -ENOKEY: + reason = "kexec of image with unavailable key"; + decide: + if (IS_ENABLED(CONFIG_KEXEC_SIG_FORCE)) { + pr_notice("%s rejected\n", reason); + goto out; + } + + ret = 0; + break; + + /* All other errors are fatal, including nomem, unparseable + * signatures and signature check failures - even if signatures + * aren't required. + */ + default: + pr_notice("kernel signature verification failed (%d).\n", ret); goto out; } - pr_debug("kernel signature verification successful.\n"); #endif /* It is possible that there no initramfs is being loaded */ if (!(flags & KEXEC_FILE_NO_INITRAMFS)) { -- 2.22.0.770.g0f2c4a37fd-goog
WARNING: multiple messages have this Message-ID (diff)
From: Matthew Garrett <matthewgarrett@google.com> To: jmorris@namei.org Cc: Jiri Bohac <jbohac@suse.cz>, linux-api@vger.kernel.org, kexec@lists.infradead.org, linux-kernel@vger.kernel.org, Matthew Garrett <mjg59@google.com>, David Howells <dhowells@redhat.com>, linux-security-module@vger.kernel.org, Dave Young <dyoung@redhat.com> Subject: [PATCH V37 08/29] kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE Date: Wed, 31 Jul 2019 15:15:56 -0700 [thread overview] Message-ID: <20190731221617.234725-9-matthewgarrett@google.com> (raw) In-Reply-To: <20190731221617.234725-1-matthewgarrett@google.com> From: Jiri Bohac <jbohac@suse.cz> This is a preparatory patch for kexec_file_load() lockdown. A locked down kernel needs to prevent unsigned kernel images from being loaded with kexec_file_load(). Currently, the only way to force the signature verification is compiling with KEXEC_VERIFY_SIG. This prevents loading usigned images even when the kernel is not locked down at runtime. This patch splits KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE. Analogous to the MODULE_SIG and MODULE_SIG_FORCE for modules, KEXEC_SIG turns on the signature verification but allows unsigned images to be loaded. KEXEC_SIG_FORCE disallows images without a valid signature. Signed-off-by: Jiri Bohac <jbohac@suse.cz> Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Matthew Garrett <mjg59@google.com> Reviewed-by: Jiri Bohac <jbohac@suse.cz> Reviewed-by: Dave Young <dyoung@redhat.com> cc: kexec@lists.infradead.org --- arch/x86/Kconfig | 20 +++++++++---- crypto/asymmetric_keys/verify_pefile.c | 4 ++- include/linux/kexec.h | 4 +-- kernel/kexec_file.c | 41 ++++++++++++++++++++++---- 4 files changed, 55 insertions(+), 14 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 05e78acb187c..fd2cd4f861cc 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2032,20 +2032,30 @@ config KEXEC_FILE config ARCH_HAS_KEXEC_PURGATORY def_bool KEXEC_FILE -config KEXEC_VERIFY_SIG +config KEXEC_SIG bool "Verify kernel signature during kexec_file_load() syscall" depends on KEXEC_FILE ---help--- - This option makes kernel signature verification mandatory for - the kexec_file_load() syscall. - In addition to that option, you need to enable signature + This option makes the kexec_file_load() syscall check for a valid + signature of the kernel image. The image can still be loaded without + a valid signature unless you also enable KEXEC_SIG_FORCE, though if + there's a signature that we can check, then it must be valid. + + In addition to this option, you need to enable signature verification for the corresponding kernel image type being loaded in order for this to work. +config KEXEC_SIG_FORCE + bool "Require a valid signature in kexec_file_load() syscall" + depends on KEXEC_SIG + ---help--- + This option makes kernel signature verification mandatory for + the kexec_file_load() syscall. + config KEXEC_BZIMAGE_VERIFY_SIG bool "Enable bzImage signature verification support" - depends on KEXEC_VERIFY_SIG + depends on KEXEC_SIG depends on SIGNED_PE_FILE_VERIFICATION select SYSTEM_TRUSTED_KEYRING ---help--- diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c index 3b303fe2f061..cc9dbcecaaca 100644 --- a/crypto/asymmetric_keys/verify_pefile.c +++ b/crypto/asymmetric_keys/verify_pefile.c @@ -96,7 +96,7 @@ static int pefile_parse_binary(const void *pebuf, unsigned int pelen, if (!ddir->certs.virtual_address || !ddir->certs.size) { pr_debug("Unsigned PE binary\n"); - return -EKEYREJECTED; + return -ENODATA; } chkaddr(ctx->header_size, ddir->certs.virtual_address, @@ -403,6 +403,8 @@ static int pefile_digest_pe(const void *pebuf, unsigned int pelen, * (*) 0 if at least one signature chain intersects with the keys in the trust * keyring, or: * + * (*) -ENODATA if there is no signature present. + * * (*) -ENOPKG if a suitable crypto module couldn't be found for a check on a * chain. * diff --git a/include/linux/kexec.h b/include/linux/kexec.h index 305f6a5ca4fe..998f77c3a0e1 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -125,7 +125,7 @@ typedef void *(kexec_load_t)(struct kimage *image, char *kernel_buf, unsigned long cmdline_len); typedef int (kexec_cleanup_t)(void *loader_data); -#ifdef CONFIG_KEXEC_VERIFY_SIG +#ifdef CONFIG_KEXEC_SIG typedef int (kexec_verify_sig_t)(const char *kernel_buf, unsigned long kernel_len); #endif @@ -134,7 +134,7 @@ struct kexec_file_ops { kexec_probe_t *probe; kexec_load_t *load; kexec_cleanup_t *cleanup; -#ifdef CONFIG_KEXEC_VERIFY_SIG +#ifdef CONFIG_KEXEC_SIG kexec_verify_sig_t *verify_sig; #endif }; diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c index b8cc032d5620..875482c34154 100644 --- a/kernel/kexec_file.c +++ b/kernel/kexec_file.c @@ -88,7 +88,7 @@ int __weak arch_kimage_file_post_load_cleanup(struct kimage *image) return kexec_image_post_load_cleanup_default(image); } -#ifdef CONFIG_KEXEC_VERIFY_SIG +#ifdef CONFIG_KEXEC_SIG static int kexec_image_verify_sig_default(struct kimage *image, void *buf, unsigned long buf_len) { @@ -186,7 +186,8 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd, const char __user *cmdline_ptr, unsigned long cmdline_len, unsigned flags) { - int ret = 0; + const char *reason; + int ret; void *ldata; loff_t size; @@ -202,14 +203,42 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd, if (ret) goto out; -#ifdef CONFIG_KEXEC_VERIFY_SIG +#ifdef CONFIG_KEXEC_SIG ret = arch_kexec_kernel_verify_sig(image, image->kernel_buf, image->kernel_buf_len); - if (ret) { - pr_debug("kernel signature verification failed.\n"); + switch (ret) { + case 0: + break; + + /* Certain verification errors are non-fatal if we're not + * checking errors, provided we aren't mandating that there + * must be a valid signature. + */ + case -ENODATA: + reason = "kexec of unsigned image"; + goto decide; + case -ENOPKG: + reason = "kexec of image with unsupported crypto"; + goto decide; + case -ENOKEY: + reason = "kexec of image with unavailable key"; + decide: + if (IS_ENABLED(CONFIG_KEXEC_SIG_FORCE)) { + pr_notice("%s rejected\n", reason); + goto out; + } + + ret = 0; + break; + + /* All other errors are fatal, including nomem, unparseable + * signatures and signature check failures - even if signatures + * aren't required. + */ + default: + pr_notice("kernel signature verification failed (%d).\n", ret); goto out; } - pr_debug("kernel signature verification successful.\n"); #endif /* It is possible that there no initramfs is being loaded */ if (!(flags & KEXEC_FILE_NO_INITRAMFS)) { -- 2.22.0.770.g0f2c4a37fd-goog _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec
next prev parent reply other threads:[~2019-07-31 22:16 UTC|newest] Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-07-31 22:15 [PATCH V37 00/29] security: Add support for locking down the kernel Matthew Garrett 2019-07-31 22:15 ` [PATCH V37 01/29] security: Support early LSMs Matthew Garrett 2019-07-31 22:15 ` [PATCH V37 02/29] security: Add a "locked down" LSM hook Matthew Garrett 2019-07-31 22:15 ` [PATCH V37 03/29] security: Add a static lockdown policy LSM Matthew Garrett 2019-07-31 22:15 ` [PATCH V37 04/29] Enforce module signatures if the kernel is locked down Matthew Garrett 2019-08-01 14:21 ` Jessica Yu 2019-08-01 20:42 ` Matthew Garrett 2019-08-08 10:01 ` Jessica Yu 2019-08-08 18:31 ` Matthew Garrett 2019-08-08 22:43 ` James Morris 2019-08-09 20:59 ` [PATCH V39] " Matthew Garrett 2019-07-31 22:15 ` [PATCH V37 05/29] Restrict /dev/{mem,kmem,port} when " Matthew Garrett 2019-07-31 22:15 ` [PATCH V37 06/29] kexec_load: Disable at runtime if " Matthew Garrett 2019-07-31 22:15 ` Matthew Garrett 2019-07-31 22:15 ` Matthew Garrett 2019-07-31 22:15 ` [PATCH V37 07/29] Copy secure_boot flag in boot params across kexec reboot Matthew Garrett 2019-07-31 22:15 ` Matthew Garrett 2019-07-31 22:15 ` Matthew Garrett [this message] 2019-07-31 22:15 ` [PATCH V37 08/29] kexec_file: split KEXEC_VERIFY_SIG into KEXEC_SIG and KEXEC_SIG_FORCE Matthew Garrett 2019-07-31 22:15 ` [PATCH V37 09/29] kexec_file: Restrict at runtime if the kernel is locked down Matthew Garrett 2019-07-31 22:15 ` Matthew Garrett 2019-07-31 22:15 ` [PATCH V37 10/29] hibernate: Disable when " Matthew Garrett 2019-07-31 22:15 ` [PATCH V37 11/29] PCI: Lock down BAR access " Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 12/29] x86: Lock down IO port " Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 13/29] x86/msr: Restrict MSR " Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 14/29] ACPI: Limit access to custom_method " Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 15/29] acpi: Ignore acpi_rsdp kernel param when the kernel has been " Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 16/29] acpi: Disable ACPI table override if the kernel is " Matthew Garrett 2019-07-31 22:16 ` Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 17/29] Prohibit PCMCIA CIS storage when " Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 18/29] Lock down TIOCSSERIAL Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 19/29] Lock down module params that specify hardware parameters (eg. ioport) Matthew Garrett 2019-08-01 16:19 ` Jessica Yu 2019-08-01 20:44 ` Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 20/29] x86/mmiotrace: Lock down the testmmiotrace module Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 21/29] Lock down /proc/kcore Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 22/29] Lock down tracing and perf kprobes when in confidentiality mode Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 23/29] bpf: Restrict bpf when kernel lockdown is " Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 24/29] Lock down perf when " Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 25/29] kexec: Allow kexec_file() with appropriate IMA policy when locked down Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 26/29] debugfs: Restrict debugfs when the kernel is " Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 27/29] tracefs: Restrict tracefs " Matthew Garrett [not found] ` <CGME20190813061053eucas1p1b6945259d9663b743e7cb32521d041e7@eucas1p1.samsung.com> 2019-08-13 6:10 ` Marek Szyprowski [not found] ` <CGME20190813072111eucas1p2b87f3f8d16c22a0a3d024bc5ebcc8bcc@eucas1p2.samsung.com> 2019-08-13 7:21 ` Marek Szyprowski [not found] ` <CGME20190814061246eucas1p128cae99a14f27bc79fa2aa72084a0413@eucas1p1.samsung.com> 2019-08-14 6:12 ` [PATCH] tracefs: Fix NULL pointer dereference when no lockdown is used Marek Szyprowski 2019-07-31 22:16 ` [PATCH V37 28/29] efi: Restrict efivar_ssdt_load when the kernel is locked down Matthew Garrett 2019-07-31 22:16 ` [PATCH V37 29/29] lockdown: Print current->comm in restriction messages Matthew Garrett
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20190731221617.234725-9-matthewgarrett@google.com \ --to=matthewgarrett@google.com \ --cc=dhowells@redhat.com \ --cc=dyoung@redhat.com \ --cc=jbohac@suse.cz \ --cc=jmorris@namei.org \ --cc=kexec@lists.infradead.org \ --cc=linux-api@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-security-module@vger.kernel.org \ --cc=mjg59@google.com \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.