The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Sriram Nambakam <snambakam@linux.microsoft.com>
To: kvm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Subject: [RFC PATCH v1 18/42] vbs: Add kexec validation and make module auth non-fatal
Date: Wed,  5 Aug 2026 04:03:00 -0700	[thread overview]
Message-ID: <20260805110324.25067-19-snambakam@linux.microsoft.com> (raw)
In-Reply-To: <20260805110324.25067-1-snambakam@linux.microsoft.com>

Add VBS/HEKI kexec validation hooks so the secure kernel (plane-1) can
approve or reject kexec kernel images before they are loaded.

kexec_file.c:
  - After signature verification passes, call vbs_kexec_validate() to
    send the kernel image GPA, size, and sig_ok flag to the secure
    kernel via the VTL call interface.
  - If the secure kernel rejects the image, kexec_file_load fails.

kexec_core.c:
  - In kimage_free(), call vbs_kexec_invalidate() to notify the secure
    kernel that a previously validated kexec image is being freed.

security/vbs/heki.h:
  - Add struct vbs_kexec_validate_req (kernel_gpa, kernel_size,
    sig_ok, flags).

security/vbs/kvm_planes.c:
  - Implement kvm_planes_kexec_validate(): translates the vmalloc
    kernel buffer to a GPA, populates the request, and issues the
    VTL call to plane-1.
  - Implement kvm_planes_kexec_invalidate(): issues the VTL call
    with no payload.

kernel/module/main.c:
  - Change VBS module validation from fatal to non-fatal.  If the
    secure kernel rejects a module, log a warning but allow loading
    to continue.  This prevents unsigned modules (common at boot)
    from blocking the system.  A strict policy can be enforced later.

Signed-off-by: Sriram Nambakam <snambakam@linux.microsoft.com>
---
 kernel/kexec_core.c       |  5 +++++
 kernel/kexec_file.c       | 20 ++++++++++++++++++++
 kernel/module/main.c      |  9 +++++----
 security/vbs/heki.h       | 14 ++++++++++++++
 security/vbs/kvm_planes.c | 24 +++++++++++++++++++++++-
 5 files changed, 67 insertions(+), 5 deletions(-)

diff --git a/kernel/kexec_core.c b/kernel/kexec_core.c
index dc770b9a6d05..a7bdbfaf68c8 100644
--- a/kernel/kexec_core.c
+++ b/kernel/kexec_core.c
@@ -43,6 +43,7 @@
 #include <linux/kmsg_dump.h>
 #include <linux/dma-map-ops.h>
 #include <linux/sysfs.h>
+#include <linux/vbs.h>
 
 #include <asm/page.h>
 #include <asm/sections.h>
@@ -580,6 +581,10 @@ void kimage_free(struct kimage *image)
 	if (!image)
 		return;
 
+	/* Notify the secure kernel that a kexec image is being freed */
+	if (vbs_available())
+		vbs_kexec_invalidate();
+
 #ifdef CONFIG_CRASH_DUMP
 	if (image->vmcoreinfo_data_copy) {
 		crash_update_vmcoreinfo_safecopy(NULL);
diff --git a/kernel/kexec_file.c b/kernel/kexec_file.c
index 2bfbb2d144e6..81cf454ab516 100644
--- a/kernel/kexec_file.c
+++ b/kernel/kexec_file.c
@@ -27,6 +27,7 @@
 #include <linux/syscalls.h>
 #include <linux/vmalloc.h>
 #include <linux/dma-map-ops.h>
+#include <linux/vbs.h>
 #include "kexec_internal.h"
 
 #ifdef CONFIG_KEXEC_SIG
@@ -243,6 +244,25 @@ kimage_file_prepare_segments(struct kimage *image, int kernel_fd, int initrd_fd,
 	if (ret)
 		goto out;
 #endif
+
+	/*
+	 * If VBS is available, ask the secure kernel (plane-1) to
+	 * validate the kexec kernel image.  Pass sig_ok based on
+	 * whether CONFIG_KEXEC_SIG is enabled and the check passed.
+	 */
+	if (vbs_available()) {
+		int sig_ok = 0;
+#ifdef CONFIG_KEXEC_SIG
+		sig_ok = 1;  /* we got here, so sig check passed */
+#endif
+		ret = vbs_kexec_validate(image->kernel_buf,
+					 image->kernel_buf_len,
+					 NULL, sig_ok);
+		if (ret) {
+			pr_warn("vbs: kexec kernel rejected by secure kernel (%d)\n", ret);
+			goto out;
+		}
+	}
 	/* It is possible that there no initramfs is being loaded */
 	if (!(flags & KEXEC_FILE_NO_INITRAMFS)) {
 		ret = kernel_read_file_from_fd(initrd_fd, 0, &image->initrd_buf,
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 2d0232fccf18..3b46d6c0fb41 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -3487,11 +3487,12 @@ static int load_module(struct load_info *info, const char __user *uargs,
 	if (vbs_available()) {
 		err = vbs_validate_module(info->hdr, info->len,
 					  NULL, info->sig_ok ? 1 : 0);
-		if (err) {
-			pr_warn("vbs: module '%s' rejected by secure kernel (%ld)\n",
+		if (err)
+			pr_warn("vbs: module '%s' validation returned (%ld) — continuing\n",
 				mod->name, err);
-			goto unlink_mod;
-		}
+		/* Non-fatal: allow loading to continue even if VBS rejects.
+		 * A strict policy can be enforced later by changing this. */
+		err = 0;
 	}
 
 	/*
diff --git a/security/vbs/heki.h b/security/vbs/heki.h
index 5b7fa92bce21..fb485f171045 100644
--- a/security/vbs/heki.h
+++ b/security/vbs/heki.h
@@ -82,6 +82,20 @@ struct vbs_unload_module_req {
 	char	name[56];	/* module name (null-terminated)          */
 } __packed;
 
+/* ── Kexec validation ─────────────────────────────────────────────────── */
+
+/*
+ * VBS_CALL_KEXEC_VALIDATE payload — plane-0 sends the GPA and size of
+ * the kexec kernel image for plane-1 validation before allowing the
+ * kexec to proceed.
+ */
+struct vbs_kexec_validate_req {
+	__u64	kernel_gpa;	/* GPA of the kernel image buffer         */
+	__u64	kernel_size;	/* size of the kernel image               */
+	__u32	sig_ok;		/* 1 if kernel's sig check passed         */
+	__u32	flags;		/* reserved, must be 0                   */
+} __packed;
+
 /* ── x86-64 page table walker (for plane-1 auditing) ─────────────────── */
 
 /* Classification of a guest-physical page based on page table walk */
diff --git a/security/vbs/kvm_planes.c b/security/vbs/kvm_planes.c
index 1114adfbd46c..061163a4d303 100644
--- a/security/vbs/kvm_planes.c
+++ b/security/vbs/kvm_planes.c
@@ -282,12 +282,34 @@ static int kvm_planes_send_certs(const void *certs, size_t certs_size)
 static int kvm_planes_kexec_validate(const void *kernel, size_t kernel_size,
 				     const void *sig, size_t sig_size)
 {
+	struct vbs_kexec_validate_req req = {};
+	struct page *page;
+
+	if (!kernel || !kernel_size)
+		return -EINVAL;
+
+	/*
+	 * sig_size is repurposed: 1 = kernel's sig check passed,
+	 * 0 = unsigned or failed (same pattern as module validation).
+	 */
+	req.sig_ok = sig_size ? 1 : 0;
+	req.kernel_size = kernel_size;
+
+	/* Get GPA of the kernel image buffer (first page) */
+	page = vmalloc_to_page(kernel);
+	if (page)
+		req.kernel_gpa = page_to_phys(page) + offset_in_page(kernel);
+
+	pr_info("vbs-kvm: kexec_validate gpa=0x%llx size=0x%llx sig_ok=%u\n",
+		req.kernel_gpa, req.kernel_size, req.sig_ok);
+
 	return kvm_planes_vtl_call(VBS_CALL_KEXEC_VALIDATE,
-				   NULL, 0, NULL, 0);
+				   &req, sizeof(req), NULL, 0);
 }
 
 static int kvm_planes_kexec_invalidate(void)
 {
+	pr_info("vbs-kvm: kexec_invalidate\n");
 	return kvm_planes_vtl_call(VBS_CALL_KEXEC_INVALIDATE,
 				   NULL, 0, NULL, 0);
 }
-- 
2.55.0


  parent reply	other threads:[~2026-08-05 11:03 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-05 11:02 [RFC PATCH v1 00/42] VBS/VSM-on-KVM: VBS integration for KVM VM planes Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 01/42] Fix merge issue - Remove duplicate definition for kvm_arch_has_irq_bypass Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 02/42] Fix compilation Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 03/42] Fix compile error Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 04/42] Fix compile errors Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 05/42] Initial support for VM Planes - Add kernel config for CONFIG_VM_PLANES - Parse vm plane config from initrd for plane configuration - Make hypercalls to allocate memory for the vm planes Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 06/42] Use vcpu count from the plane configuration Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 07/42] skip processing plane configuration for plane 0 - plane 0 is the boot plane Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 08/42] Add plane config param to specify kernel image format Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 09/42] Activate the VM Planes through the Hypervisor - Using KVM as the VMM Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 10/42] allow the command line to be specified for kernels in other planes Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 11/42] Various changes to support VM Planes Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 12/42] Add a Virtualization Based Security (VBS) framework. - Add backends for AMD SEV-SNP, Intel TDX, Arm CCA and KVM Planes. - Support VTL on Hyper-V in addition to Planes on KVM Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 13/42] Add a inter-plane communication mechanism through KVM. - model this to use a single page similar to SEV-SNP Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 14/42] KVM: Add per-plane memory attribute support for cross-plane EPT protection Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 15/42] KVM: x86: Add KVM_HC_VBS_VTL_CALL hypercall for VBS inter-plane calls Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 16/42] vbs: Add HEKI kernel sealing and fix KVM plane memory attribute guards Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 17/42] vbs: Add module authentication via VBS/HEKI Sriram Nambakam
2026-08-05 11:03 ` Sriram Nambakam [this message]
2026-08-05 11:03 ` [RFC PATCH v1 19/42] Merge branch 'master' into vm-planes Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 20/42] kvm: x86: fix merged plane API/stat build regressions Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 21/42] KVM: x86: exit VM planes and VBS hypercalls to userspace Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 22/42] kexec: block legacy kexec_load when VBS is active Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 23/42] kvm: x86: fix merged plane API/stat build regressions Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 24/42] KVM: planes: expose memory-attribute setting to in-kernel callers Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 25/42] vm_planes: drop unused per-plane vcpu_count Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 26/42] drivers/virt: add VBS secure-plane park loop Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 27/42] KVM: planes: add arch-neutral in-kernel plane switch helper Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 28/42] KVM: x86: add VBS VTL call/return and cross-plane set-mem-attrs hypercalls Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 29/42] init/vm_planes: set up planes from rootfs_initcall and load ELF payloads Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 30/42] security/vbs: run backend probe and HEKI seal at rootfs_initcall Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 31/42] security/vbs: pin the VTL call hypercall to CPU0 Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 32/42] security/vbs: add secure-plane monitor backend Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 33/42] drivers/virt: rename VBS park loop to secure_monitor Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 34/42] x86/realmode: skip the sub-1M trampoline for the VBS secure plane Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 35/42] KVM: x86: deny normal-plane access to secure-plane memory Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 36/42] KVM: plane: handle KVM_CHECK_EXTENSION on the plane fd Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 37/42] KVM: selftests: run plane tests with a split IRQ chip Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 38/42] kvm: x86: drop obsolete kvm_cache_regs.h Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 39/42] kvm: arch: finalize plane hooks and kvm_arch_vcpu_create signature Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 40/42] kvm: x86: use kvm_vcpu scheduling-state accessors and struct stat fields Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 41/42] kvm: x86: finalize per-plane APIC state and CPUID placement Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 42/42] kvm: planes: reconcile core plane state, UAPI and hypercall exit Sriram Nambakam

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=20260805110324.25067-19-snambakam@linux.microsoft.com \
    --to=snambakam@linux.microsoft.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    /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: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox