[PATCH v3 1/2] misc: ibmasm: Fix static out-of-bounds MMIO access during probe
From: w15303746062
Date: Tue Jun 23 2026 - 08:44:13 EST
From: Mingyu Wang <25181214217@xxxxxxxxxxxxxxxxx>
The ibmasm driver maps PCI BAR 0 without verifying if the hardware-provided
resource length is sufficient to cover statically accessed registers.
When evaluating the driver against emulated hardware or during virtual
device fuzzing, a malformed device may expose a significantly undersized
BAR 0. This leads to an out-of-bounds (OOB) access when reading the
INTR_CONTROL_REGISTER (offset 0x13A4) during probe. A page fault here
while holding the idempotent_init_module() lock causes a cascading global
soft lockup.
Fix this by storing the mapped size in 'struct service_processor' and
ensuring the BAR is at least large enough to cover the highest statically
accessed hardware register before calling pci_ioremap_bar().
Fixes: bdbeed75b288 ("pci: use pci_ioremap_bar() in drivers/misc")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Mingyu Wang <25181214217@xxxxxxxxxxxxxxxxx>
---
drivers/misc/ibmasm/ibmasm.h | 1 +
drivers/misc/ibmasm/lowlevel.h | 3 +++
drivers/misc/ibmasm/module.c | 13 +++++++++++++
3 files changed, 17 insertions(+)
diff --git a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h
index a5ced88ca923..8d69198bf10f 100644
--- a/drivers/misc/ibmasm/ibmasm.h
+++ b/drivers/misc/ibmasm/ibmasm.h
@@ -140,6 +140,7 @@ struct service_processor {
struct list_head node;
spinlock_t lock;
void __iomem *base_address;
+ resource_size_t mapped_size;
unsigned int irq;
struct command *current_command;
struct command *heartbeat;
diff --git a/drivers/misc/ibmasm/lowlevel.h b/drivers/misc/ibmasm/lowlevel.h
index 25f1ed07c3c5..c2d2e96ec4e9 100644
--- a/drivers/misc/ibmasm/lowlevel.h
+++ b/drivers/misc/ibmasm/lowlevel.h
@@ -33,6 +33,9 @@
#define INTR_STATUS_REGISTER 0x13A0
#define INTR_CONTROL_REGISTER 0x13A4
+/* Highest statically accessed register offset */
+#define IBMASM_MAX_REG_OFFSET INTR_CONTROL_REGISTER
+
#define SCOUT_COM_A_BASE 0x0000
#define SCOUT_COM_B_BASE 0x0100
#define SCOUT_COM_C_BASE 0x0200
diff --git a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c
index 4509c15a76a8..87d4d698a5ff 100644
--- a/drivers/misc/ibmasm/module.c
+++ b/drivers/misc/ibmasm/module.c
@@ -93,6 +93,19 @@ static int ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
}
sp->irq = pdev->irq;
+ sp->mapped_size = pci_resource_len(pdev, 0);
+
+ /*
+ * Ensure BAR 0 is large enough to cover the highest statically
+ * accessed hardware register (IBMASM_MAX_REG_OFFSET).
+ */
+ if (sp->mapped_size < IBMASM_MAX_REG_OFFSET + 4) {
+ dev_err(sp->dev, "PCI BAR0 too small, need at least %zu bytes\n",
+ (size_t)(IBMASM_MAX_REG_OFFSET + 4));
+ result = -ENODEV;
+ goto error_ioremap;
+ }
+
sp->base_address = pci_ioremap_bar(pdev, 0);
if (!sp->base_address) {
dev_err(sp->dev, "Failed to ioremap pci memory\n");
--
2.34.1