[PATCH -next] firmware: imx: secure-enclave: fix overflow in iobuf size calculation

Pankaj Gupta posted 1 patch 1 month ago
drivers/firmware/imx/se_ctrl.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
[PATCH -next] firmware: imx: secure-enclave: fix overflow in iobuf size calculation
Posted by Pankaj Gupta 1 month ago
Validate user-provided buffer length before alignment to avoid integer
overflow in round_up(). An overflow could result in allocating zero
bytes and subsequently accessing memory out of bounds.

Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Closes: https://lore.kernel.org/linux-next/20260507.smatch.iobuf/
Fixes: 4de71839142b ("firmware: drivers: imx: adds miscdev")
Signed-off-by: Pankaj Gupta <pankaj.gupta@nxp.com>
---
 drivers/firmware/imx/se_ctrl.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/drivers/firmware/imx/se_ctrl.c b/drivers/firmware/imx/se_ctrl.c
index d2f7780054a3..d5cc37273d8e 100644
--- a/drivers/firmware/imx/se_ctrl.c
+++ b/drivers/firmware/imx/se_ctrl.c
@@ -646,6 +646,7 @@ static int se_ioctl_setup_iobuf_handler(struct se_if_device_ctx *dev_ctx,
 {
 	struct se_shared_mem *shared_mem = NULL;
 	struct se_ioctl_setup_iobuf io = {0};
+	size_t aligned_len;
 	int err = 0;
 	u32 pos;
 
@@ -669,16 +670,23 @@ static int se_ioctl_setup_iobuf_handler(struct se_if_device_ctx *dev_ctx,
 		goto copy;
 	}
 
+	if (io.length > SIZE_MAX - 7) {
+		dev_err(dev_ctx->priv->dev, "%s: Invalid buffer length.",
+			dev_ctx->devname);
+		return -EINVAL;
+	}
+	aligned_len = round_up((size_t)io.length, 8);
+
 	/* No specific requirement for this buffer. */
 	shared_mem = &dev_ctx->se_shared_mem_mgmt.non_secure_mem;
 
 	/* Check there is enough space in the shared memory. */
-	dev_dbg(dev_ctx->priv->dev, "%s: req_size = %d, max_size= %d, curr_pos = %d",
-		dev_ctx->devname, round_up(io.length, 8u), shared_mem->size,
+	dev_dbg(dev_ctx->priv->dev, "%s: req_size = %zd, max_size= %d, curr_pos = %d",
+		dev_ctx->devname, aligned_len, shared_mem->size,
 		shared_mem->pos);
 
 	if (shared_mem->size < shared_mem->pos ||
-	    round_up(io.length, 8u) > (shared_mem->size - shared_mem->pos)) {
+	    aligned_len > (shared_mem->size - shared_mem->pos)) {
 		dev_err(dev_ctx->priv->dev, "%s: Not enough space in shared memory.",
 			dev_ctx->devname);
 		return -ENOMEM;
@@ -686,7 +694,7 @@ static int se_ioctl_setup_iobuf_handler(struct se_if_device_ctx *dev_ctx,
 
 	/* Allocate space in shared memory. 8 bytes aligned. */
 	pos = shared_mem->pos;
-	shared_mem->pos += round_up(io.length, 8u);
+	shared_mem->pos += aligned_len;
 	io.ele_addr = (u64)shared_mem->dma_addr + pos;
 
 	memset(shared_mem->ptr + pos, 0, io.length);
-- 
2.43.0