Merge branch 'asoc-5.4' into asoc-5.5
[linux-2.6-microblaze.git] / kernel / kexec_file.c
index b8cc032..79f252a 100644 (file)
@@ -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)
 {
@@ -177,6 +177,59 @@ void kimage_file_post_load_cleanup(struct kimage *image)
        image->image_loader_data = NULL;
 }
 
+#ifdef CONFIG_KEXEC_SIG
+static int
+kimage_validate_signature(struct kimage *image)
+{
+       const char *reason;
+       int ret;
+
+       ret = arch_kexec_kernel_verify_sig(image, image->kernel_buf,
+                                          image->kernel_buf_len);
+       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);
+                       return ret;
+               }
+
+               /* If IMA is guaranteed to appraise a signature on the kexec
+                * image, permit it even if the kernel is otherwise locked
+                * down.
+                */
+               if (!ima_appraise_signature(READING_KEXEC_IMAGE) &&
+                   security_locked_down(LOCKDOWN_KEXEC))
+                       return -EPERM;
+
+               return 0;
+
+               /* 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);
+       }
+
+       return ret;
+}
+#endif
+
 /*
  * In file mode list of segments is prepared by kernel. Copy relevant
  * data from user space, do error checking, prepare segment list
@@ -186,7 +239,7 @@ 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;
+       int ret;
        void *ldata;
        loff_t size;
 
@@ -202,14 +255,11 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
        if (ret)
                goto out;
 
-#ifdef CONFIG_KEXEC_VERIFY_SIG
-       ret = arch_kexec_kernel_verify_sig(image, image->kernel_buf,
-                                          image->kernel_buf_len);
-       if (ret) {
-               pr_debug("kernel signature verification failed.\n");
+#ifdef CONFIG_KEXEC_SIG
+       ret = kimage_validate_signature(image);
+
+       if (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)) {