[PATCH 21/28] mfd: loongson-se: Validate engine ID, DMA buffer size, and IRQ registration
From: Lee Jones
Date: Wed Oct 21 2026 - 08:27:02 EST
Harden input and error checking in loongson_se_init_engine() and
loongson_se_probe():
- Reject out-of-bounds engine IDs and engine 0 in
loongson_se_init_engine() before indexing se->engines.
- Store dmam_size as u32 to match device_property_read_u32() and verify
that it is large enough to hold the command buffers of all engines
within engine 0's data region.
- Propagate negative error codes from platform_irq_count(),
platform_get_irq(), and devm_request_irq() instead of ignoring IRQ
registration failures or masking -EPROBE_DEFER.
Fixes: e551fa3159e3 ("mfd: Add support for Loongson Security Engine chip controller")
Closes: https://sashiko.dev/#/bug/linux-89bf25f5-ecd9-40e3-bb4c-bd26d07c53a1
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Lee Jones <lee@xxxxxxxxxx>
---
drivers/mfd/loongson-se.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/drivers/mfd/loongson-se.c b/drivers/mfd/loongson-se.c
index bdbab4b91729..23af05d388aa 100644
--- a/drivers/mfd/loongson-se.c
+++ b/drivers/mfd/loongson-se.c
@@ -26,7 +26,7 @@ struct loongson_se {
struct completion cmd_completion;
void *dmam_base;
- int dmam_size;
+ u32 dmam_size;
struct mutex engine_init_lock;
struct loongson_se_engine engines[SE_ENGINE_MAX];
@@ -101,8 +101,13 @@ EXPORT_SYMBOL_GPL(loongson_se_send_engine_cmd);
struct loongson_se_engine *loongson_se_init_engine(struct device *dev, int id)
{
struct loongson_se *se = dev_get_drvdata(dev);
- struct loongson_se_engine *engine = &se->engines[id];
struct loongson_se_controller_cmd cmd = {};
+ struct loongson_se_engine *engine;
+
+ if (id <= 0 || id >= SE_ENGINE_MAX)
+ return NULL;
+
+ engine = &se->engines[id];
engine->se = se;
engine->id = id;
@@ -186,7 +191,7 @@ static void loongson_se_stop(void *data)
mutex_unlock(&se->engine_init_lock);
}
-static int loongson_se_init(struct loongson_se *se, dma_addr_t addr, int size)
+static int loongson_se_init(struct loongson_se *se, dma_addr_t addr, u32 size)
{
struct loongson_se_controller_cmd cmd = {};
int err;
@@ -249,6 +254,9 @@ static int loongson_se_probe(struct platform_device *pdev)
if (device_property_read_u32(dev, "dmam_size", &se->dmam_size))
return -ENODEV;
+ if ((se->dmam_size / SE_ENGINE_MAX) < (SE_ENGINE_MAX * 2 * SE_ENGINE_CMD_SIZE))
+ return -EINVAL;
+
se->dmam_base = dmam_alloc_coherent(dev, se->dmam_size, &paddr, GFP_KERNEL);
if (!se->dmam_base)
return -ENOMEM;
@@ -258,16 +266,21 @@ static int loongson_se_probe(struct platform_device *pdev)
return PTR_ERR(se->base);
nr_irq = platform_irq_count(pdev);
- if (nr_irq <= 0)
+ if (!nr_irq)
return -ENODEV;
+ if (nr_irq < 0)
+ return nr_irq;
writel(SE_INT_ALL, se->base + SE_S2LINT_CL);
for (i = 0; i < nr_irq; i++) {
irq = platform_get_irq(pdev, i);
+ if (irq < 0)
+ return irq;
+
err = devm_request_irq(dev, irq, se_irq_handler, 0, "loongson-se", se);
if (err)
- dev_err(dev, "failed to request IRQ: %d\n", irq);
+ return dev_err_probe(dev, err, "Failed to request IRQ: %d\n", irq);
}
writel(SE_INT_ALL, se->base + SE_S2LINT_EN);
--
2.56.0.218.g1ec904b173-goog