Kernel KVM virtualization development
 help / color / mirror / Atom feed
* [PATCH 0/2] LoongArch: KVM: EIOINTC: fix INT_ENCODE ipnum out-of-bounds access
@ 2026-07-14  1:24 Tao Cui
  2026-07-14  1:24 ` [PATCH 1/2] LoongArch: KVM: EIOINTC: clamp ipnum to valid range in INT_ENCODE mode Tao Cui
  2026-07-14  1:24 ` [PATCH 2/2] LoongArch: KVM: EIOINTC: factor IP-number decode into a helper Tao Cui
  0 siblings, 2 replies; 7+ messages in thread
From: Tao Cui @ 2026-07-14  1:24 UTC (permalink / raw)
  To: zhaotianrui, maobibo, chenhuacai
  Cc: kernel, lixianglai, kvm, loongarch, linux-kernel, stable, Tao Cui

From: Tao Cui <cuitao@kylinos.cn>

This small series fixes a guest-triggerable out-of-bounds access in the
LoongArch KVM EIOINTC emulation, then factors the duplicated IP-number
decode into a helper.

The IP-number decode in eiointc_set_sw_coreisr() and eiointc_update_irq()
bounds ipnum only in the default (1-hot) mode. In INT_ENCODE mode the raw
ipmap byte (0..255) is used to index sw_coreisr[cpu][ipnum], whose second
dimension is LOONGSON_IP_NUM (8), so any ipmap byte >= 8 reads/writes past
the array. The value is guest-programmable through the EIOINTC virtual
extension (VIRT_CONFIG enables INT_ENCODE and the IPMAP IOCSR write is not
validated) and is also restored from a migration stream via the
LOAD_FINISHED control attribute, so this is a host slab out-of-bounds
access reachable from an unprivileged guest.

Patch 1 is the minimal, stable-bound fix: clamp ipnum to [0, LOONGSON_IP_NUM)
in INT_ENCODE mode at both call sites. Patch 2 is a follow-up cleanup that
extracts the now-identical decode into eiointc_get_ipnum() (no functional
change); it is split out so the fix stays surgical for backporting.

Verified with KASAN on Loongson-3A6000: the device-attr restore sequence
(INT_ENCODE + ipmap byte 0x80 + LOAD_FINISHED) reports
"BUG: KASAN: slab-out-of-bounds in eiointc_set_sw_coreisr" without the
series and is clean with it.

Patch 1 carries Fixes:/Cc: stable; patch 2 is mainline-only.

Tao Cui (2):
  LoongArch: KVM: EIOINTC: clamp ipnum to valid range in INT_ENCODE mode
  LoongArch: KVM: EIOINTC: factor IP-number decode into a helper

 arch/loongarch/kvm/intc/eiointc.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

--
2.43.0

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

* [PATCH 1/2] LoongArch: KVM: EIOINTC: clamp ipnum to valid range in INT_ENCODE mode
  2026-07-14  1:24 [PATCH 0/2] LoongArch: KVM: EIOINTC: fix INT_ENCODE ipnum out-of-bounds access Tao Cui
@ 2026-07-14  1:24 ` Tao Cui
  2026-07-14  1:39   ` sashiko-bot
  2026-07-14  2:32   ` Bibo Mao
  2026-07-14  1:24 ` [PATCH 2/2] LoongArch: KVM: EIOINTC: factor IP-number decode into a helper Tao Cui
  1 sibling, 2 replies; 7+ messages in thread
From: Tao Cui @ 2026-07-14  1:24 UTC (permalink / raw)
  To: zhaotianrui, maobibo, chenhuacai
  Cc: kernel, lixianglai, kvm, loongarch, linux-kernel, stable, Tao Cui

From: Tao Cui <cuitao@kylinos.cn>

The IP-number decode in eiointc_set_sw_coreisr() and eiointc_update_irq()
clamps ipnum only in the default (1-hot) mode. In INT_ENCODE mode the raw
ipmap byte (0..255) is used as the index into sw_coreisr[cpu][ipnum],
whose second dimension is LOONGSON_IP_NUM (8), so any ipmap byte >= 8
accesses the array out of bounds.

The value is guest-programmable through the EIOINTC virtual extension
(VIRT_CONFIG enables INT_ENCODE and the IPMAP IOCSR write is unvalidated)
and is also restored unvalidated from a migration stream via the
LOAD_FINISHED control attribute, resulting in a host slab out-of-bounds
access reachable from an unprivileged guest.

Clamp ipnum to [0, LOONGSON_IP_NUM) in INT_ENCODE mode as well.

Fixes: 3956a52bc05b ("LoongArch: KVM: Add EIOINTC read and write functions")
Cc: stable@vger.kernel.org
Signed-off-by: Tao Cui <cuitao@kylinos.cn>
---
 arch/loongarch/kvm/intc/eiointc.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 2b14485d14a7..0c34d7ab264d 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -17,6 +17,8 @@ static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s)
 		if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
 			ipnum = count_trailing_zeros(ipnum);
 			ipnum = ipnum < 4 ? ipnum : 0;
+		} else {
+			ipnum = (ipnum < LOONGSON_IP_NUM) ? ipnum : 0;
 		}
 
 		cpuid = ((u8 *)s->coremap)[irq];
@@ -42,6 +44,8 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
 	if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
 		ipnum = count_trailing_zeros(ipnum);
 		ipnum = ipnum < 4 ? ipnum : 0;
+	} else {
+		ipnum = (ipnum < LOONGSON_IP_NUM) ? ipnum : 0;
 	}
 
 	cpu = s->sw_coremap[irq];
-- 
2.43.0


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

* [PATCH 2/2] LoongArch: KVM: EIOINTC: factor IP-number decode into a helper
  2026-07-14  1:24 [PATCH 0/2] LoongArch: KVM: EIOINTC: fix INT_ENCODE ipnum out-of-bounds access Tao Cui
  2026-07-14  1:24 ` [PATCH 1/2] LoongArch: KVM: EIOINTC: clamp ipnum to valid range in INT_ENCODE mode Tao Cui
@ 2026-07-14  1:24 ` Tao Cui
  2026-07-14  1:37   ` sashiko-bot
  1 sibling, 1 reply; 7+ messages in thread
From: Tao Cui @ 2026-07-14  1:24 UTC (permalink / raw)
  To: zhaotianrui, maobibo, chenhuacai
  Cc: kernel, lixianglai, kvm, loongarch, linux-kernel, stable, Tao Cui

From: Tao Cui <cuitao@kylinos.cn>

The ipmap IP-number decode is duplicated in eiointc_set_sw_coreisr() and
eiointc_update_irq(). Factor it into eiointc_get_ipnum().

No functional change.

Signed-off-by: Tao Cui <cuitao@kylinos.cn>
---
 arch/loongarch/kvm/intc/eiointc.c | 30 ++++++++++++++++--------------
 1 file changed, 16 insertions(+), 14 deletions(-)

diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
index 0c34d7ab264d..c1e0cd8dca16 100644
--- a/arch/loongarch/kvm/intc/eiointc.c
+++ b/arch/loongarch/kvm/intc/eiointc.c
@@ -7,19 +7,27 @@
 #include <asm/kvm_vcpu.h>
 #include <linux/count_zeros.h>
 
+static int eiointc_get_ipnum(struct loongarch_eiointc *s, int irq)
+{
+	int ipnum = (s->ipmap >> (irq / 32 * 8)) & 0xff;
+
+	if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
+		ipnum = count_trailing_zeros(ipnum);
+		ipnum = ipnum < 4 ? ipnum : 0;
+	} else {
+		ipnum = (ipnum < LOONGSON_IP_NUM) ? ipnum : 0;
+	}
+
+	return ipnum;
+}
+
 static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s)
 {
 	int ipnum, cpu, cpuid, irq;
 	struct kvm_vcpu *vcpu;
 
 	for (irq = 0; irq < EIOINTC_IRQS; irq++) {
-		ipnum = (s->ipmap >> (irq / 32 * 8)) & 0xff;
-		if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
-			ipnum = count_trailing_zeros(ipnum);
-			ipnum = ipnum < 4 ? ipnum : 0;
-		} else {
-			ipnum = (ipnum < LOONGSON_IP_NUM) ? ipnum : 0;
-		}
+		ipnum = eiointc_get_ipnum(s, irq);
 
 		cpuid = ((u8 *)s->coremap)[irq];
 		vcpu = kvm_get_vcpu_by_cpuid(s->kvm, cpuid);
@@ -40,13 +48,7 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
 	struct kvm_vcpu *vcpu;
 	struct kvm_interrupt vcpu_irq;
 
-	ipnum = (s->ipmap >> (irq / 32 * 8)) & 0xff;
-	if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
-		ipnum = count_trailing_zeros(ipnum);
-		ipnum = ipnum < 4 ? ipnum : 0;
-	} else {
-		ipnum = (ipnum < LOONGSON_IP_NUM) ? ipnum : 0;
-	}
+	ipnum = eiointc_get_ipnum(s, irq);
 
 	cpu = s->sw_coremap[irq];
 	vcpu = kvm_get_vcpu_by_id(s->kvm, cpu);
-- 
2.43.0


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

* Re: [PATCH 2/2] LoongArch: KVM: EIOINTC: factor IP-number decode into a helper
  2026-07-14  1:24 ` [PATCH 2/2] LoongArch: KVM: EIOINTC: factor IP-number decode into a helper Tao Cui
@ 2026-07-14  1:37   ` sashiko-bot
  0 siblings, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-07-14  1:37 UTC (permalink / raw)
  To: Tao Cui; +Cc: kvm

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

Pre-existing issues:
- [Critical] Missing bounds check on untrusted guest-controlled MSI data (`e->msi.data`) allows out-of-bounds array accesses and arbitrary host memory corruption.
--

--- Patch [2]: [PATCH 2/2] LoongArch: KVM: EIOINTC: factor IP-number decode into a helper ---
commit 819d482a674f6e7813eb24d40a7c6711789b26a8
Author: Tao Cui <cuitao@kylinos.cn>

LoongArch: KVM: EIOINTC: factor IP-number decode into a helper

This commit factors the ipmap IP-number decoding logic, which was previously
duplicated in eiointc_set_sw_coreisr() and eiointc_update_irq(), into a new
helper function named eiointc_get_ipnum().

> diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
> index 0c34d7ab264dc..c1e0cd8dca16c 100644
> --- a/arch/loongarch/kvm/intc/eiointc.c
> +++ b/arch/loongarch/kvm/intc/eiointc.c
> @@ -7,19 +7,27 @@
>  #include <asm/kvm_vcpu.h>
>  #include <linux/count_zeros.h>
>  
> +static int eiointc_get_ipnum(struct loongarch_eiointc *s, int irq)
> +{
> +	int ipnum = (s->ipmap >> (irq / 32 * 8)) & 0xff;

[Severity: Critical]
This is a pre-existing issue, but does this bit shift result in undefined
behavior if an out-of-bounds irq is provided?

If a malicious guest or userspace provides an unvalidated MSI data payload,
it is passed as the irq parameter through the following call chain:

kvm_send_userspace_msi() -> kvm_set_msi() -> pch_msi_set_irq()

pch_msi_set_irq() {
    ...
    eiointc_set_irq(kvm->arch.eiointc, e->msi.data, level);
}

The unvalidated irq is used in the bit shift above, and also leads to
out-of-bounds array reads in eiointc_update_irq():

    cpu = s->sw_coremap[irq];

Could this also allow arbitrary host memory corruption when setting bits in
eiointc_set_irq() since isr is bounded to EIOINTC_IRQS?

    level ? __set_bit(irq, isr) : __clear_bit(irq, isr);

> +
> +	if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
> +		ipnum = count_trailing_zeros(ipnum);

[ ... ]

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260714012452.1021833-1-cui.tao@linux.dev?part=2

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

* Re: [PATCH 1/2] LoongArch: KVM: EIOINTC: clamp ipnum to valid range in INT_ENCODE mode
  2026-07-14  1:24 ` [PATCH 1/2] LoongArch: KVM: EIOINTC: clamp ipnum to valid range in INT_ENCODE mode Tao Cui
@ 2026-07-14  1:39   ` sashiko-bot
  2026-07-14  2:32   ` Bibo Mao
  1 sibling, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-07-14  1:39 UTC (permalink / raw)
  To: Tao Cui; +Cc: kvm

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

Pre-existing issues:
- [Critical] Guest or host userspace can trigger massive out-of-bounds reads and writes on the host kernel heap and undefined bitshift behavior by supplying an unvalidated MSI data value.
- [High] `eiointc_set_sw_coreisr` fails to decode `cpuid` in 1-hot mode (`EIOINTC_ENABLE_CPU_ENCODE` disabled), reading from the wrong vCPU's `coreisr` state when reconstructing `sw_coreisr` during `LOAD_FINISHED`.
- [High] When a guest writes to `EIOINTC_COREISR_START` to clear a pending interrupt, `eiointc_update_irq` clears the fast-path state (`sw_coreisr`) and de-asserts the parent IRQ on the currently routed CPU from `sw_coremap`, which may not be the CPU whose `coreisr` was actually cleared.
- [Medium] Lockless access to `map->phys_map[cpuid]` in `kvm_get_vcpu_by_cpuid()` lacks memory barriers.
--

--- Patch [1]: [PATCH 1/2] LoongArch: KVM: EIOINTC: clamp ipnum to valid range in INT_ENCODE mode ---
commit 21ec11994b801fe6a14903dedc825bbe4a3246e5
Author: Tao Cui <cuitao@kylinos.cn>

LoongArch: KVM: EIOINTC: clamp ipnum to valid range in INT_ENCODE mode
    
This commit clamps the ipnum variable to [0, LOONGSON_IP_NUM) in INT_ENCODE
mode. It prevents out-of-bounds accesses on the sw_coreisr array which is
guest-programmable, preventing out-of-bounds accesses reachable from an
unprivileged guest.

Cc: stable@vger.kernel.org

> diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
> index 2b14485d14a70..0c34d7ab264dc 100644
> --- a/arch/loongarch/kvm/intc/eiointc.c
> +++ b/arch/loongarch/kvm/intc/eiointc.c
> @@ -17,6 +17,8 @@ static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s)
>  		if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
>  			ipnum = count_trailing_zeros(ipnum);
>  			ipnum = ipnum < 4 ? ipnum : 0;
> +		} else {
> +			ipnum = (ipnum < LOONGSON_IP_NUM) ? ipnum : 0;
>  		}
>  
>  		cpuid = ((u8 *)s->coremap)[irq];

[Severity: High]
This is a pre-existing issue, but does eiointc_set_sw_coreisr() fail to
decode cpuid in 1-hot mode when EIOINTC_ENABLE_CPU_ENCODE is disabled?

It looks like it fetches cpuid directly from s->coremap[irq] without decoding
it. In the default 1-hot mode, cpuid represents a bitmask, but the subsequent
call to kvm_get_vcpu_by_cpuid() expects an exact ID. Could this result in
looking up the wrong vCPU during state restoration, causing lost interrupts?

[Severity: Medium]
This is a pre-existing issue, but is the lockless access to
map->phys_map[cpuid] safe in kvm_get_vcpu_by_cpuid() when called here?

When kvm_get_vcpu_by_cpuid() reads map->phys_map[cpuid].enabled and vcpu, it
doesn't use memory barriers like smp_load_acquire(). Concurrently,
kvm_set_cpuid() updates these fields using a lock but without
smp_store_release(). Could this compiler or CPU reordering cause
kvm_get_vcpu_by_cpuid() to transiently return NULL?

[ ... ]

> @@ -42,6 +44,8 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
>  	if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
>  		ipnum = count_trailing_zeros(ipnum);
>  		ipnum = ipnum < 4 ? ipnum : 0;
> +	} else {
> +		ipnum = (ipnum < LOONGSON_IP_NUM) ? ipnum : 0;
>  	}
>  
>  	cpu = s->sw_coremap[irq];

[Severity: Critical]
This is a pre-existing issue, but is the irq index validated before being
used for array accesses here?

The KVM MSI routing mechanism allows guests or host userspace to inject MSIs
with an arbitrary 32-bit msi.data payload. In pch_msi_set_irq():

arch/loongarch/kvm/intc/pch_pic.c:pch_msi_set_irq() {
    ...
    eiointc_set_irq(kvm->arch.eiointc, e->msi.data, level);
    ...
}

The user-supplied e->msi.data is passed unvalidated to eiointc_set_irq() as
the irq parameter. This unvalidated irq is then used as an index for bitwise
operations like __set_bit(irq, isr) in eiointc_set_irq() and array accesses
like s->sw_coremap[irq] in eiointc_update_irq(). Can this allow unprivileged
guest code to perform arbitrary out-of-bounds memory writes on the host
kernel heap?

[Severity: High]
This isn't a bug introduced by this patch, but does eiointc_update_irq()
operate on the correct CPU when clearing a pending interrupt?

When a guest writes to EIOINTC_COREISR_START to clear a pending interrupt:

arch/loongarch/kvm/intc/eiointc.c:loongarch_eiointc_write() {
    ...
    eiointc_update_irq(s, irq + index * 64, 0);
    ...
}

The write handler issues the clear request without explicitly passing the
original vCPU. Then eiointc_update_irq() dynamically fetches the target CPU
from s->sw_coremap[irq]. If the guest has re-routed the IRQ while it was
pending, sw_coremap will point to the new CPU. Will this clear the fast-path
sw_coreisr state on the new CPU, leaving the old CPU with a permanently
asserted parent IRQ and an unrecoverable interrupt storm?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260714012452.1021833-1-cui.tao@linux.dev?part=1

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

* Re: [PATCH 1/2] LoongArch: KVM: EIOINTC: clamp ipnum to valid range in INT_ENCODE mode
  2026-07-14  1:24 ` [PATCH 1/2] LoongArch: KVM: EIOINTC: clamp ipnum to valid range in INT_ENCODE mode Tao Cui
  2026-07-14  1:39   ` sashiko-bot
@ 2026-07-14  2:32   ` Bibo Mao
  2026-07-14  3:19     ` Tao Cui
  1 sibling, 1 reply; 7+ messages in thread
From: Bibo Mao @ 2026-07-14  2:32 UTC (permalink / raw)
  To: Tao Cui, zhaotianrui, chenhuacai
  Cc: kernel, lixianglai, kvm, loongarch, linux-kernel, stable, Tao Cui

Hi Tao,

Thanks to catch this, there is similar modification which can be located at:
https://lore.kernel.org/lkml/20260709082109.1361767-5-maobibo@loongson.cn/

Regards
Bibo Mao

On 2026/7/14 上午9:24, Tao Cui wrote:
> From: Tao Cui <cuitao@kylinos.cn>
> 
> The IP-number decode in eiointc_set_sw_coreisr() and eiointc_update_irq()
> clamps ipnum only in the default (1-hot) mode. In INT_ENCODE mode the raw
> ipmap byte (0..255) is used as the index into sw_coreisr[cpu][ipnum],
> whose second dimension is LOONGSON_IP_NUM (8), so any ipmap byte >= 8
> accesses the array out of bounds.
> 
> The value is guest-programmable through the EIOINTC virtual extension
> (VIRT_CONFIG enables INT_ENCODE and the IPMAP IOCSR write is unvalidated)
> and is also restored unvalidated from a migration stream via the
> LOAD_FINISHED control attribute, resulting in a host slab out-of-bounds
> access reachable from an unprivileged guest.
> 
> Clamp ipnum to [0, LOONGSON_IP_NUM) in INT_ENCODE mode as well.
> 
> Fixes: 3956a52bc05b ("LoongArch: KVM: Add EIOINTC read and write functions")
> Cc: stable@vger.kernel.org
> Signed-off-by: Tao Cui <cuitao@kylinos.cn>
> ---
>   arch/loongarch/kvm/intc/eiointc.c | 4 ++++
>   1 file changed, 4 insertions(+)
> 
> diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
> index 2b14485d14a7..0c34d7ab264d 100644
> --- a/arch/loongarch/kvm/intc/eiointc.c
> +++ b/arch/loongarch/kvm/intc/eiointc.c
> @@ -17,6 +17,8 @@ static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s)
>   		if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
>   			ipnum = count_trailing_zeros(ipnum);
>   			ipnum = ipnum < 4 ? ipnum : 0;
> +		} else {
> +			ipnum = (ipnum < LOONGSON_IP_NUM) ? ipnum : 0;
>   		}
>   
>   		cpuid = ((u8 *)s->coremap)[irq];
> @@ -42,6 +44,8 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
>   	if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
>   		ipnum = count_trailing_zeros(ipnum);
>   		ipnum = ipnum < 4 ? ipnum : 0;
> +	} else {
> +		ipnum = (ipnum < LOONGSON_IP_NUM) ? ipnum : 0;
>   	}
>   
>   	cpu = s->sw_coremap[irq];
> 


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

* Re: [PATCH 1/2] LoongArch: KVM: EIOINTC: clamp ipnum to valid range in INT_ENCODE mode
  2026-07-14  2:32   ` Bibo Mao
@ 2026-07-14  3:19     ` Tao Cui
  0 siblings, 0 replies; 7+ messages in thread
From: Tao Cui @ 2026-07-14  3:19 UTC (permalink / raw)
  To: Bibo Mao, zhaotianrui, chenhuacai
  Cc: cui.tao, kernel, lixianglai, kvm, loongarch, linux-kernel, stable,
	Tao Cui



在 2026/7/14 10:32, Bibo Mao 写道:
> Hi Tao,
> 
> Thanks to catch this, there is similar modification which can be located at:
> https://lore.kernel.org/lkml/20260709082109.1361767-5-maobibo@loongson.cn/
> 
Hi Bibo,

Haha, looks like we raced to the same fix :) I came across it while
debugging VM migration (the LOAD_FINISHED restore path). Your patch
takes priority — I'll go ahead and drop my series.

Thanks,
Tao

> Regards
> Bibo Mao
> 
> On 2026/7/14 上午9:24, Tao Cui wrote:
>> From: Tao Cui <cuitao@kylinos.cn>
>>
>> The IP-number decode in eiointc_set_sw_coreisr() and eiointc_update_irq()
>> clamps ipnum only in the default (1-hot) mode. In INT_ENCODE mode the raw
>> ipmap byte (0..255) is used as the index into sw_coreisr[cpu][ipnum],
>> whose second dimension is LOONGSON_IP_NUM (8), so any ipmap byte >= 8
>> accesses the array out of bounds.
>>
>> The value is guest-programmable through the EIOINTC virtual extension
>> (VIRT_CONFIG enables INT_ENCODE and the IPMAP IOCSR write is unvalidated)
>> and is also restored unvalidated from a migration stream via the
>> LOAD_FINISHED control attribute, resulting in a host slab out-of-bounds
>> access reachable from an unprivileged guest.
>>
>> Clamp ipnum to [0, LOONGSON_IP_NUM) in INT_ENCODE mode as well.
>>
>> Fixes: 3956a52bc05b ("LoongArch: KVM: Add EIOINTC read and write functions")
>> Cc: stable@vger.kernel.org
>> Signed-off-by: Tao Cui <cuitao@kylinos.cn>
>> ---
>>   arch/loongarch/kvm/intc/eiointc.c | 4 ++++
>>   1 file changed, 4 insertions(+)
>>
>> diff --git a/arch/loongarch/kvm/intc/eiointc.c b/arch/loongarch/kvm/intc/eiointc.c
>> index 2b14485d14a7..0c34d7ab264d 100644
>> --- a/arch/loongarch/kvm/intc/eiointc.c
>> +++ b/arch/loongarch/kvm/intc/eiointc.c
>> @@ -17,6 +17,8 @@ static void eiointc_set_sw_coreisr(struct loongarch_eiointc *s)
>>           if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
>>               ipnum = count_trailing_zeros(ipnum);
>>               ipnum = ipnum < 4 ? ipnum : 0;
>> +        } else {
>> +            ipnum = (ipnum < LOONGSON_IP_NUM) ? ipnum : 0;
>>           }
>>             cpuid = ((u8 *)s->coremap)[irq];
>> @@ -42,6 +44,8 @@ static void eiointc_update_irq(struct loongarch_eiointc *s, int irq, int level)
>>       if (!(s->status & BIT(EIOINTC_ENABLE_INT_ENCODE))) {
>>           ipnum = count_trailing_zeros(ipnum);
>>           ipnum = ipnum < 4 ? ipnum : 0;
>> +    } else {
>> +        ipnum = (ipnum < LOONGSON_IP_NUM) ? ipnum : 0;
>>       }
>>         cpu = s->sw_coremap[irq];
>>
> 


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

end of thread, other threads:[~2026-07-14  3:19 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-14  1:24 [PATCH 0/2] LoongArch: KVM: EIOINTC: fix INT_ENCODE ipnum out-of-bounds access Tao Cui
2026-07-14  1:24 ` [PATCH 1/2] LoongArch: KVM: EIOINTC: clamp ipnum to valid range in INT_ENCODE mode Tao Cui
2026-07-14  1:39   ` sashiko-bot
2026-07-14  2:32   ` Bibo Mao
2026-07-14  3:19     ` Tao Cui
2026-07-14  1:24 ` [PATCH 2/2] LoongArch: KVM: EIOINTC: factor IP-number decode into a helper Tao Cui
2026-07-14  1:37   ` sashiko-bot

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