All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Sean Christopherson <seanjc@google.com>,
	Paolo Bonzini <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	 Sashiko Bot <sashiko-bot@kernel.org>,
	Yan Zhao <yan.y.zhao@intel.com>,
	 Binbin Wu <binbin.wu@linux.intel.com>,
	Ackerley Tng <ackerleytng@google.com>,
	 Haotian Jiang <jianghaotian.sunday@gmail.com>
Subject: [PATCH v2 1/2] KVM: TDX: Reject INIT_MEM_REGION if number of bytes would overflow a u64
Date: Thu,  6 Aug 2026 10:06:01 -0700	[thread overview]
Message-ID: <20260806170602.4112602-2-seanjc@google.com> (raw)
In-Reply-To: <20260806170602.4112602-1-seanjc@google.com>

From: Haotian Jiang <jianghaotian.sunday@gmail.com>

The nr_pages field in struct kvm_tdx_init_mem_region is a u64 that comes
directly from userspace via copy_from_user().  The current validation
uses a manual overflow check:

  region.gpa + (region.nr_pages << PAGE_SHIFT) <= region.gpa

When nr_pages >= 2^52, the shift (nr_pages << PAGE_SHIFT) wraps around
to a small value, bypassing the wrap check.  While downstream protections
(gfn_to_memslot() returning NULL for GFNs outside any memslot, and
kvm_slot_has_gmem() checking for NULL) prevent any actual out-of-bounds
access, the overflow itself is a real bug that should be caught at the
validation layer.

Replace the manual overflow check with check_shl_overflow() to correctly
detect the wrap-around.

Note, the manual wrap-around check on the gpa+size technically has a benign
off-by-one bug, and can also use check_add_overflow().  Those flaws will be
addressed shortly.

Opportunistically separate the initial sanity checks from the more involved
checks to try and make the code easier to read.

Fixes: c846b451d3c5 ("KVM: TDX: Add an ioctl to create initial guest memory")
Reported-by: Sashiko Bot <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260630214952.98C851F000E9@smtp.kernel.org
Cc: Yan Zhao <yan.y.zhao@intel.com>
Cc: Binbin Wu <binbin.wu@linux.intel.com>
Cc: Ackerley Tng <ackerleytng@google.com>
Signed-off-by: Haotian Jiang <jianghaotian.sunday@gmail.com>
[sean: use gpa_t, isolate check_shl_overflow() change, tweak changelog]
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
 arch/x86/kvm/vmx/tdx.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c
index b272c20586a7..929115aeb9ec 100644
--- a/arch/x86/kvm/vmx/tdx.c
+++ b/arch/x86/kvm/vmx/tdx.c
@@ -3219,6 +3219,7 @@ static int tdx_vcpu_init_mem_region(struct kvm_vcpu *vcpu, struct kvm_tdx_cmd *c
 	struct kvm_tdx *kvm_tdx = to_kvm_tdx(kvm);
 	struct kvm_tdx_init_mem_region region;
 	struct tdx_gmem_post_populate_arg arg;
+	gpa_t nr_bytes;
 	long gmem_ret;
 	int ret;
 
@@ -3236,10 +3237,13 @@ static int tdx_vcpu_init_mem_region(struct kvm_vcpu *vcpu, struct kvm_tdx_cmd *c
 		return -EFAULT;
 
 	if (!PAGE_ALIGNED(region.source_addr) || !region.source_addr ||
-	    !PAGE_ALIGNED(region.gpa) || !region.nr_pages ||
-	    region.gpa + (region.nr_pages << PAGE_SHIFT) <= region.gpa ||
+	    !PAGE_ALIGNED(region.gpa) || !region.nr_pages)
+		return -EINVAL;
+
+	if (check_shl_overflow(region.nr_pages, PAGE_SHIFT, &nr_bytes) ||
+	    region.gpa + nr_bytes <= region.gpa ||
 	    !vt_is_tdx_private_gpa(kvm, region.gpa) ||
-	    !vt_is_tdx_private_gpa(kvm, region.gpa + (region.nr_pages << PAGE_SHIFT) - 1))
+	    !vt_is_tdx_private_gpa(kvm, region.gpa + nr_bytes - 1))
 		return -EINVAL;
 
 	ret = 0;
-- 
2.55.0.679.g6767b8d81c-goog


  reply	other threads:[~2026-08-06 17:06 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-06 17:06 [PATCH v2 0/2] KVM: TDX: INIT_MEM_REGION fixes Sean Christopherson
2026-08-06 17:06 ` Sean Christopherson [this message]
2026-08-10  6:27   ` [PATCH v2 1/2] KVM: TDX: Reject INIT_MEM_REGION if number of bytes would overflow a u64 Yan Zhao
2026-08-10  8:45   ` Binbin Wu
2026-08-06 17:06 ` [PATCH v2 2/2] KVM: TDX: Fix a benign off-by-one bug on the end GPA for INIT_MEM_REGION Sean Christopherson
2026-08-10  6:58   ` Yan Zhao
2026-08-10  9:23   ` Binbin Wu

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=20260806170602.4112602-2-seanjc@google.com \
    --to=seanjc@google.com \
    --cc=ackerleytng@google.com \
    --cc=binbin.wu@linux.intel.com \
    --cc=jianghaotian.sunday@gmail.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=sashiko-bot@kernel.org \
    --cc=yan.y.zhao@intel.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: link
Be 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.