[PATCH] hw/intc/loongarch_pch_pic: Validate htmsi_vector before indexing parent_irq

Bin Guo posted 1 patch 1 week, 6 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20260804073445.55612-1-guobin@linux.alibaba.com
Maintainers: Song Gao <17746591750@163.com>, Bibo Mao <maobibo@loongson.cn>, Xianglai Li <lixianglai@loongson.cn>, Jiaxun Yang <jiaxun.yang@flygoat.com>
hw/intc/loongarch_pch_pic.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
[PATCH] hw/intc/loongarch_pch_pic: Validate htmsi_vector before indexing parent_irq
Posted by Bin Guo 1 week, 6 days ago
pch_pic_update_irq() used the guest-writable htmsi_vector[irq] value as an
index into parent_irq[] without checking bounds.  A value >= irq_num (64 in
the array, but only 32 are used by the virt machine) causes an out-of-bounds
read and a guest-triggerable QEMU crash.

Validate the vector before calling qemu_set_irq() in both the raise and lower
paths and log a guest error if it is out of range.

Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4114
Cc: qemu-stable@nongnu.org
Signed-off-by: Bin Guo <guobin@linux.alibaba.com>
---
 hw/intc/loongarch_pch_pic.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c
index 82e16be391..e87c7497c1 100644
--- a/hw/intc/loongarch_pch_pic.c
+++ b/hw/intc/loongarch_pch_pic.c
@@ -19,13 +19,21 @@ static void pch_pic_update_irq(LoongArchPICCommonState *s, uint64_t mask,
 {
     uint64_t val;
     int irq;
+    uint8_t vector;
 
     if (level) {
         val = mask & s->intirr & ~s->int_mask;
         if (val) {
             irq = ctz64(val);
+            vector = s->htmsi_vector[irq];
+            if (vector >= s->irq_num) {
+                qemu_log_mask(LOG_GUEST_ERROR,
+                              "%s: htmsi_vector[%d]=%u out of range\n",
+                              __func__, irq, vector);
+                return;
+            }
             s->intisr |= MAKE_64BIT_MASK(irq, 1);
-            qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
+            qemu_set_irq(s->parent_irq[vector], 1);
         }
     } else {
         /*
@@ -35,8 +43,15 @@ static void pch_pic_update_irq(LoongArchPICCommonState *s, uint64_t mask,
         val = mask & s->intisr & ~s->intirr;
         if (val) {
             irq = ctz64(val);
+            vector = s->htmsi_vector[irq];
+            if (vector >= s->irq_num) {
+                qemu_log_mask(LOG_GUEST_ERROR,
+                              "%s: htmsi_vector[%d]=%u out of range\n",
+                              __func__, irq, vector);
+                return;
+            }
             s->intisr &= ~MAKE_64BIT_MASK(irq, 1);
-            qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 0);
+            qemu_set_irq(s->parent_irq[vector], 0);
         }
     }
 }
-- 
2.50.1 (Apple Git-155)
Re: [PATCH] hw/intc/loongarch_pch_pic: Validate htmsi_vector before indexing parent_irq
Posted by Bibo Mao 1 week, 5 days ago
On 2026/8/4 下午3:34, Bin Guo wrote:
> pch_pic_update_irq() used the guest-writable htmsi_vector[irq] value as an
> index into parent_irq[] without checking bounds.  A value >= irq_num (64 in
> the array, but only 32 are used by the virt machine) causes an out-of-bounds
> read and a guest-triggerable QEMU crash.
> 
> Validate the vector before calling qemu_set_irq() in both the raise and lower
> paths and log a guest error if it is out of range.
> 
> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4114
> Cc: qemu-stable@nongnu.org
> Signed-off-by: Bin Guo <guobin@linux.alibaba.com>
> ---
>   hw/intc/loongarch_pch_pic.c | 19 +++++++++++++++++--
>   1 file changed, 17 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c
> index 82e16be391..e87c7497c1 100644
> --- a/hw/intc/loongarch_pch_pic.c
> +++ b/hw/intc/loongarch_pch_pic.c
> @@ -19,13 +19,21 @@ static void pch_pic_update_irq(LoongArchPICCommonState *s, uint64_t mask,
>   {
>       uint64_t val;
>       int irq;
> +    uint8_t vector;
>   
>       if (level) {
>           val = mask & s->intirr & ~s->int_mask;
>           if (val) {
>               irq = ctz64(val);
> +            vector = s->htmsi_vector[irq];
> +            if (vector >= s->irq_num) {
> +                qemu_log_mask(LOG_GUEST_ERROR,
> +                              "%s: htmsi_vector[%d]=%u out of range\n",
> +                              __func__, irq, vector);
> +                return;
> +            }
>               s->intisr |= MAKE_64BIT_MASK(irq, 1);
> -            qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
> +            qemu_set_irq(s->parent_irq[vector], 1);
>           }
>       } else {
>           /*
> @@ -35,8 +43,15 @@ static void pch_pic_update_irq(LoongArchPICCommonState *s, uint64_t mask,
>           val = mask & s->intisr & ~s->intirr;
>           if (val) {
>               irq = ctz64(val);
> +            vector = s->htmsi_vector[irq];
> +            if (vector >= s->irq_num) {
> +                qemu_log_mask(LOG_GUEST_ERROR,
> +                              "%s: htmsi_vector[%d]=%u out of range\n",
> +                              __func__, irq, vector);
> +                return;
> +            }
>               s->intisr &= ~MAKE_64BIT_MASK(irq, 1);
> -            qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 0);
> +            qemu_set_irq(s->parent_irq[vector], 0);
>           }
>       }
>   }
> 
Hi Bin,

Thanks for solving this problem.

Reviewed-by: Bibo Mao <maobibo@loongson.cn>

Regards
Bibo Mao