Kernel KVM virtualization development
 help / color / mirror / Atom feed
* [PATCH] KVM: x86: Add IDT limit check in __emulate_int_real()
@ 2026-06-08 12:35 Kayra Cizmeci
  2026-06-08 12:35 ` [PATCH] Linux 7.1-rc7 Kayra Cizmeci
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Kayra Cizmeci @ 2026-06-08 12:35 UTC (permalink / raw)
  To: seanjc, pbonzini
  Cc: tglx, mingo, bp, dave.hansen, x86, hpa, kvm, linux-kernel,
	linux-kbuild, Kayra Cizmeci

During real mode interrupt emulation, KVM currently pushes data to the
stack before checking IDT limits.

This patch fetches the IDT early and injects a #GP if the limit
is exceeded. This prevents potential corruption.

Signed-off-by: Kayra Cizmeci <kayracizmeci@gmail.com>
---
 arch/x86/kvm/emulate.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 8013dccb3110..04e6c80bdb14 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2022,7 +2022,11 @@ static int __emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq)
 	gva_t eip_addr;
 	u16 cs, eip;
 
-	/* TODO: Add limit checks */
+	ops->get_idt(ctxt, &dt);
+
+	if (dt.size < (irq << 2) + 3)
+		return emulate_gp(ctxt, 0);
+
 	ctxt->src.val = ctxt->eflags;
 	rc = em_push(ctxt);
 	if (rc != X86EMUL_CONTINUE)
@@ -2040,8 +2044,6 @@ static int __emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq)
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
-	ops->get_idt(ctxt, &dt);
-
 	eip_addr = dt.address + (irq << 2);
 	cs_addr = dt.address + (irq << 2) + 2;
 
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH] Linux 7.1-rc7
  2026-06-08 12:35 [PATCH] KVM: x86: Add IDT limit check in __emulate_int_real() Kayra Cizmeci
@ 2026-06-08 12:35 ` Kayra Cizmeci
  2026-06-08 12:56 ` [PATCH] KVM: x86: Add IDT limit check in __emulate_int_real() sashiko-bot
  2026-06-08 13:46 ` [PATCH v2] " Kayra Cizmeci
  2 siblings, 0 replies; 4+ messages in thread
From: Kayra Cizmeci @ 2026-06-08 12:35 UTC (permalink / raw)
  To: seanjc, pbonzini
  Cc: tglx, mingo, bp, dave.hansen, x86, hpa, kvm, linux-kernel,
	linux-kbuild, Linus Torvalds

From: Linus Torvalds <torvalds@linux-foundation.org>

---
 Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index e3aabcda1ff7..e156e2696efe 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@
 VERSION = 7
 PATCHLEVEL = 1
 SUBLEVEL = 0
-EXTRAVERSION = -rc6
+EXTRAVERSION = -rc7
 NAME = Baby Opossum Posse
 
 # *DOCUMENTATION*
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] KVM: x86: Add IDT limit check in __emulate_int_real()
  2026-06-08 12:35 [PATCH] KVM: x86: Add IDT limit check in __emulate_int_real() Kayra Cizmeci
  2026-06-08 12:35 ` [PATCH] Linux 7.1-rc7 Kayra Cizmeci
@ 2026-06-08 12:56 ` sashiko-bot
  2026-06-08 13:46 ` [PATCH v2] " Kayra Cizmeci
  2 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-06-08 12:56 UTC (permalink / raw)
  To: Kayra Cizmeci; +Cc: kvm

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] IDT limit check is bypassed for software interrupt vectors >= 128 due to sign-extension, leaving an out-of-bounds memory read and undefined behavior unaddressed.
--

commit 1d15914e95742042e4c5113eceda0a57155cbdd4
Author: Kayra Cizmeci <kayracizmeci@gmail.com>

KVM: x86: Add IDT limit check in __emulate_int_real()

During real mode interrupt emulation, KVM currently pushes data to the
stack before checking IDT limits. This commit fetches the IDT early and
injects a #GP if the limit is exceeded.

> diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
> index c8e292e9a24df..ca9685a778c56 100644
> --- a/arch/x86/kvm/emulate.c
> +++ b/arch/x86/kvm/emulate.c
> @@ -2009,7 +2009,11 @@ static int __emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq)
>  	gva_t eip_addr;
>  	u16 cs, eip;
>  
> -	/* TODO: Add limit checks */
> +	ops->get_idt(ctxt, &dt);
> +
> +	if (dt.size < (irq << 2) + 3)
> +		return emulate_gp(ctxt, 0);

[Severity: High]
This is a pre-existing issue, but does this check protect against software
interrupt vectors >= 128?

The KVM instruction decoder treats the immediate operand of the INT n
instruction (opcode 0xcd) as a sign-extended byte (SrcImmByte in the opcode
table). This causes the decoder to sign-extend vectors like INT 0x80 to a
negative number.

When a negative vector is passed to __emulate_int_real() as the irq
parameter, (irq << 2) results in undefined behavior due to left-shifting a
negative integer.

Furthermore, dt.size is an unsigned short, which promotes to a signed int
during the comparison. If irq is negative, the right-hand side of the
comparison is negative, causing the dt.size check to evaluate to false and
silently bypass the intended protection.

This would then allow the emulator to calculate a negative offset for
dt.address + (irq << 2) and read out-of-bounds memory.

Could the decoder be updated to use SrcImmUByte for opcode 0xcd, or could
the irq parameter be handled as an unsigned value to prevent this bypass?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260608123503.23298-1-kayracizmeci@gmail.com?part=1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2] KVM: x86: Add IDT limit check in __emulate_int_real()
  2026-06-08 12:35 [PATCH] KVM: x86: Add IDT limit check in __emulate_int_real() Kayra Cizmeci
  2026-06-08 12:35 ` [PATCH] Linux 7.1-rc7 Kayra Cizmeci
  2026-06-08 12:56 ` [PATCH] KVM: x86: Add IDT limit check in __emulate_int_real() sashiko-bot
@ 2026-06-08 13:46 ` Kayra Cizmeci
  2 siblings, 0 replies; 4+ messages in thread
From: Kayra Cizmeci @ 2026-06-08 13:46 UTC (permalink / raw)
  To: seanjc, pbonzini
  Cc: tglx, mingo, bp, dave.hansen, x86, hpa, kvm, linux-kernel,
	Kayra Cizmeci

During real mode interrupt emulation, KVM currently pushes data to the
stack before checking IDT limits.

This patch fetches the IDT early and injects a #GP if the limit
is exceeded. This prevents potential corruption.

Signed-off-by: Kayra Cizmeci <kayracizmeci@gmail.com>
---
 arch/x86/kvm/emulate.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 8013dccb3110..32168db07dd2 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -2022,7 +2022,11 @@ static int __emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq)
 	gva_t eip_addr;
 	u16 cs, eip;
 
-	/* TODO: Add limit checks */
+	ops->get_idt(ctxt, &dt);
+
+	if (dt.size < (irq << 2) + 3)
+		return emulate_gp(ctxt, 0);
+
 	ctxt->src.val = ctxt->eflags;
 	rc = em_push(ctxt);
 	if (rc != X86EMUL_CONTINUE)
@@ -2040,8 +2044,6 @@ static int __emulate_int_real(struct x86_emulate_ctxt *ctxt, int irq)
 	if (rc != X86EMUL_CONTINUE)
 		return rc;
 
-	ops->get_idt(ctxt, &dt);
-
 	eip_addr = dt.address + (irq << 2);
 	cs_addr = dt.address + (irq << 2) + 2;
 
@@ -4324,7 +4326,7 @@ static const struct opcode opcode_table[256] = {
 	I(Stack, em_leave),
 	I(ImplicitOps | SrcImmU16 | IsBranch | ShadowStack, em_ret_far_imm),
 	I(ImplicitOps | IsBranch | ShadowStack, em_ret_far),
-	D(ImplicitOps | IsBranch), DI(SrcImmByte | IsBranch | ShadowStack, intn),
+	D(ImplicitOps | IsBranch), DI(SrcImmUByte | IsBranch | ShadowStack, intn),
 	D(ImplicitOps | No64 | IsBranch),
 	II(ImplicitOps | IsBranch | ShadowStack, em_iret, iret),
 	/* 0xD0 - 0xD7 */
-- 
2.54.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-06-08 13:47 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-08 12:35 [PATCH] KVM: x86: Add IDT limit check in __emulate_int_real() Kayra Cizmeci
2026-06-08 12:35 ` [PATCH] Linux 7.1-rc7 Kayra Cizmeci
2026-06-08 12:56 ` [PATCH] KVM: x86: Add IDT limit check in __emulate_int_real() sashiko-bot
2026-06-08 13:46 ` [PATCH v2] " Kayra Cizmeci

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox