aboutsummaryrefslogtreecommitdiffstats
path: root/queue-6.15/loongarch-kvm-avoid-overflow-with-array-index.patch
diff options
Diffstat (limited to 'queue-6.15/loongarch-kvm-avoid-overflow-with-array-index.patch')
-rw-r--r--queue-6.15/loongarch-kvm-avoid-overflow-with-array-index.patch99
1 files changed, 99 insertions, 0 deletions
diff --git a/queue-6.15/loongarch-kvm-avoid-overflow-with-array-index.patch b/queue-6.15/loongarch-kvm-avoid-overflow-with-array-index.patch
new file mode 100644
index 0000000000..4a3bc56893
--- /dev/null
+++ b/queue-6.15/loongarch-kvm-avoid-overflow-with-array-index.patch
@@ -0,0 +1,99 @@
+From 080e8d2ecdfde588897aa8a87a8884061f4dbbbb Mon Sep 17 00:00:00 2001
+From: Bibo Mao <maobibo@loongson.cn>
+Date: Thu, 26 Jun 2025 20:07:27 +0800
+Subject: LoongArch: KVM: Avoid overflow with array index
+
+From: Bibo Mao <maobibo@loongson.cn>
+
+commit 080e8d2ecdfde588897aa8a87a8884061f4dbbbb upstream.
+
+The variable index is modified and reused as array index when modify
+register EIOINTC_ENABLE. There will be array index overflow problem.
+
+Cc: stable@vger.kernel.org
+Fixes: 3956a52bc05b ("LoongArch: KVM: Add EIOINTC read and write functions")
+Signed-off-by: Bibo Mao <maobibo@loongson.cn>
+Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/loongarch/kvm/intc/eiointc.c | 17 +++++++----------
+ 1 file changed, 7 insertions(+), 10 deletions(-)
+
+diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
+index f39929d7bf8a..9c47456b805c 100644
+--- a/arch/loongarch/kvm/intc/eiointc.c
++++ b/arch/loongarch/kvm/intc/eiointc.c
+@@ -436,17 +436,16 @@ static int loongarch_eiointc_writew(struct kvm_vcpu *vcpu,
+ break;
+ case EIOINTC_ENABLE_START ... EIOINTC_ENABLE_END:
+ index = (offset - EIOINTC_ENABLE_START) >> 1;
+- old_data = s->enable.reg_u32[index];
++ old_data = s->enable.reg_u16[index];
+ s->enable.reg_u16[index] = data;
+ /*
+ * 1: enable irq.
+ * update irq when isr is set.
+ */
+ data = s->enable.reg_u16[index] & ~old_data & s->isr.reg_u16[index];
+- index = index << 1;
+ for (i = 0; i < sizeof(data); i++) {
+ u8 mask = (data >> (i * 8)) & 0xff;
+- eiointc_enable_irq(vcpu, s, index + i, mask, 1);
++ eiointc_enable_irq(vcpu, s, index * 2 + i, mask, 1);
+ }
+ /*
+ * 0: disable irq.
+@@ -455,7 +454,7 @@ static int loongarch_eiointc_writew(struct kvm_vcpu *vcpu,
+ data = ~s->enable.reg_u16[index] & old_data & s->isr.reg_u16[index];
+ for (i = 0; i < sizeof(data); i++) {
+ u8 mask = (data >> (i * 8)) & 0xff;
+- eiointc_enable_irq(vcpu, s, index, mask, 0);
++ eiointc_enable_irq(vcpu, s, index * 2 + i, mask, 0);
+ }
+ break;
+ case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
+@@ -529,10 +528,9 @@ static int loongarch_eiointc_writel(struct kvm_vcpu *vcpu,
+ * update irq when isr is set.
+ */
+ data = s->enable.reg_u32[index] & ~old_data & s->isr.reg_u32[index];
+- index = index << 2;
+ for (i = 0; i < sizeof(data); i++) {
+ u8 mask = (data >> (i * 8)) & 0xff;
+- eiointc_enable_irq(vcpu, s, index + i, mask, 1);
++ eiointc_enable_irq(vcpu, s, index * 4 + i, mask, 1);
+ }
+ /*
+ * 0: disable irq.
+@@ -541,7 +539,7 @@ static int loongarch_eiointc_writel(struct kvm_vcpu *vcpu,
+ data = ~s->enable.reg_u32[index] & old_data & s->isr.reg_u32[index];
+ for (i = 0; i < sizeof(data); i++) {
+ u8 mask = (data >> (i * 8)) & 0xff;
+- eiointc_enable_irq(vcpu, s, index, mask, 0);
++ eiointc_enable_irq(vcpu, s, index * 4 + i, mask, 0);
+ }
+ break;
+ case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
+@@ -615,10 +613,9 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
+ * update irq when isr is set.
+ */
+ data = s->enable.reg_u64[index] & ~old_data & s->isr.reg_u64[index];
+- index = index << 3;
+ for (i = 0; i < sizeof(data); i++) {
+ u8 mask = (data >> (i * 8)) & 0xff;
+- eiointc_enable_irq(vcpu, s, index + i, mask, 1);
++ eiointc_enable_irq(vcpu, s, index * 8 + i, mask, 1);
+ }
+ /*
+ * 0: disable irq.
+@@ -627,7 +624,7 @@ static int loongarch_eiointc_writeq(struct kvm_vcpu *vcpu,
+ data = ~s->enable.reg_u64[index] & old_data & s->isr.reg_u64[index];
+ for (i = 0; i < sizeof(data); i++) {
+ u8 mask = (data >> (i * 8)) & 0xff;
+- eiointc_enable_irq(vcpu, s, index, mask, 0);
++ eiointc_enable_irq(vcpu, s, index * 8 + i, mask, 0);
+ }
+ break;
+ case EIOINTC_BOUNCE_START ... EIOINTC_BOUNCE_END:
+--
+2.50.0
+