From: Bin Guo <guobin@linux.alibaba.com>
To: qemu-devel@nongnu.org
Cc: peter.maydell@linaro.org, philmd@mailo.com, farosas@suse.de,
lvivier@redhat.com, pbonzini@redhat.com, qemu-arm@nongnu.org
Subject: [PATCH] hw/intc/bcm2835_ic: reject out-of-range FIQ source values
Date: Mon, 31 Aug 2026 16:17:09 +0800 [thread overview]
Message-ID: <20260831081709.77725-1-guobin@linux.alibaba.com> (raw)
The FIQ_CONTROL register accepts a 7-bit source selector, but only
sources 0..71 (64 GPU + 8 ARM IRQs) exist. Values 96..127 cause
bcm2835_ic_update() to call extract32(arm_irq_level, start, 1) with
start >= 32, which trips the assertion in bitops.h and aborts QEMU.
Reject writes that select a non-existent source and log a guest error,
so that a malicious or buggy guest cannot kill the emulator.
Add a qtest that verifies both valid and out-of-range FIQ source
selections on raspi3b.
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4368
Signed-off-by: Bin Guo <guobin@linux.alibaba.com>
---
hw/intc/bcm2835_ic.c | 13 +++++--
tests/qtest/bcm2835-ic-test.c | 66 +++++++++++++++++++++++++++++++++++
tests/qtest/meson.build | 2 +-
3 files changed, 78 insertions(+), 3 deletions(-)
create mode 100644 tests/qtest/bcm2835-ic-test.c
diff --git a/hw/intc/bcm2835_ic.c b/hw/intc/bcm2835_ic.c
index 71bf671761..262a620968 100644
--- a/hw/intc/bcm2835_ic.c
+++ b/hw/intc/bcm2835_ic.c
@@ -139,10 +139,19 @@ static void bcm2835_ic_write(void *opaque, hwaddr offset, uint64_t val,
BCM2835ICState *s = opaque;
switch (offset) {
- case FIQ_CONTROL:
- s->fiq_select = extract32(val, 0, 7);
+ case FIQ_CONTROL: {
+ unsigned fiq_select = extract32(val, 0, 7);
+
+ if (fiq_select >= GPU_IRQS + ARM_IRQS) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: FIQ select %u out of range\n",
+ __func__, fiq_select);
+ return;
+ }
+ s->fiq_select = fiq_select;
s->fiq_enable = extract32(val, 7, 1);
break;
+ }
case IRQ_ENABLE_1:
s->gpu_irq_enable |= val;
break;
diff --git a/tests/qtest/bcm2835-ic-test.c b/tests/qtest/bcm2835-ic-test.c
new file mode 100644
index 0000000000..1e171ee092
--- /dev/null
+++ b/tests/qtest/bcm2835-ic-test.c
@@ -0,0 +1,66 @@
+/*
+ * QTest testcase for the BCM2835 Interrupt Controller
+ *
+ * Copyright (c) 2026 Bin Guo <guobin@linux.alibaba.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest-single.h"
+
+#define IC_BASE 0x3f00b200
+#define FIQ_CONTROL (IC_BASE + 0x0c)
+
+static void test_fiq_select_out_of_range(void)
+{
+ uint32_t val;
+
+ /*
+ * Only FIQ sources 0..71 exist. Source 96 used to trigger an assertion
+ * in bcm2835_ic_update() because extract32(arm_irq_level, 32, 1) was
+ * called with start >= 32. Make sure the write is rejected and QEMU
+ * keeps running.
+ */
+ writel(FIQ_CONTROL, 0xe0); /* fiq_select = 96, fiq_enable = 1 */
+ val = readl(FIQ_CONTROL);
+ g_assert_cmpint(val, ==, 0);
+
+ /* The first source past the ARM IRQ range should also be rejected. */
+ writel(FIQ_CONTROL, 0xc8); /* fiq_select = 72, fiq_enable = 1 */
+ val = readl(FIQ_CONTROL);
+ g_assert_cmpint(val, ==, 0);
+}
+
+static void test_fiq_select_valid(void)
+{
+ uint32_t val;
+
+ /* Select the highest valid ARM IRQ source (64 + 7 = 71). */
+ writel(FIQ_CONTROL, 0xc7); /* fiq_select = 71, fiq_enable = 1 */
+ val = readl(FIQ_CONTROL);
+ g_assert_cmpint(val, ==, 0xc7);
+
+ /* Select the highest valid GPU IRQ source. */
+ writel(FIQ_CONTROL, 0x3f); /* fiq_select = 63, fiq_enable = 0 */
+ val = readl(FIQ_CONTROL);
+ g_assert_cmpint(val, ==, 0x3f);
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+
+ g_test_init(&argc, &argv, NULL);
+
+ qtest_add_func("/bcm2835/bcm2835-ic/fiq-select-out-of-range",
+ test_fiq_select_out_of_range);
+ qtest_add_func("/bcm2835/bcm2835-ic/fiq-select-valid",
+ test_fiq_select_valid);
+
+ qtest_start("-machine raspi3b");
+ ret = g_test_run();
+ qtest_end();
+
+ return ret;
+}
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index a13c4af989..149b395e53 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -274,7 +274,7 @@ qtests_aarch64 = \
['tpm-tis-device-test', 'tpm-tis-device-swtpm-test'] : []) + \
(config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ? ['xlnx-can-test', 'fuzz-xlnx-dp-test'] : []) + \
(config_all_devices.has_key('CONFIG_XLNX_VERSAL') ? ['xlnx-canfd-test', 'xlnx-versal-trng-test'] : []) + \
- (config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test', 'bcm2835-i2c-test'] : []) + \
+ (config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test', 'bcm2835-i2c-test', 'bcm2835-ic-test'] : []) + \
(config_all_accel.has_key('CONFIG_TCG') and \
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test', 'tpm-tis-i2c-swtpm-test'] : []) + \
(config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed64 : []) + \
--
2.50.1 (Apple Git-155)
next reply other threads:[~2026-08-31 8:17 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-31 8:17 Bin Guo [this message]
2026-08-31 10:06 ` [PATCH] hw/intc/bcm2835_ic: reject out-of-range FIQ source values Philippe Mathieu-Daudé
2026-09-08 10:52 ` Peter Maydell
2026-09-16 4:37 ` Michael Tokarev
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260831081709.77725-1-guobin@linux.alibaba.com \
--to=guobin@linux.alibaba.com \
--cc=farosas@suse.de \
--cc=lvivier@redhat.com \
--cc=pbonzini@redhat.com \
--cc=peter.maydell@linaro.org \
--cc=philmd@mailo.com \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.