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.patch | 99 |
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 + |