[PATCH] rapidio: avoid out-of-bounds copies in CM list ioctls
From: Yousef Alhouseen
Date: Wed Jun 24 2026 - 13:19:41 EST
The RapidIO channelized messaging list ioctls allocate response buffers
for the number of entries that will be copied into the buffer, but two
paths copy back a larger count to userspace.
cm_ep_get_list() caps the endpoint entries at min(user_count, npeers),
while cm_mport_get_list() stores at most the user-supplied capacity.
Both functions still used the uncapped count in copy_to_user(), which can
read beyond the allocated buffer and leak adjacent kernel memory.
Copy only the header and the entries that were actually written to the
temporary buffer. The reported count remains the real total so callers
can retry with a larger buffer.
Signed-off-by: Yousef Alhouseen <alhouseenyousef@xxxxxxxxx>
---
drivers/rapidio/rio_cm.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/rapidio/rio_cm.c b/drivers/rapidio/rio_cm.c
index c55af5924..9dec8be5f 100644
--- a/drivers/rapidio/rio_cm.c
+++ b/drivers/rapidio/rio_cm.c
@@ -1602,7 +1602,7 @@ static int cm_ep_get_list(void __user *arg)
((u32 *)buf)[0] = i; /* report an updated number of entries */
((u32 *)buf)[1] = info[1]; /* put back an mport ID */
- if (copy_to_user(arg, buf, sizeof(u32) * (info[0] + 2)))
+ if (copy_to_user(arg, buf, sizeof(u32) * (i + 2)))
ret = -EFAULT;
kfree(buf);
@@ -1619,7 +1619,7 @@ static int cm_mport_get_list(void __user *arg)
void *buf;
struct cm_dev *cm;
u32 *entry_ptr;
- int count = 0;
+ int copied = 0, count = 0;
if (copy_from_user(&entries, arg, sizeof(entries)))
return -EFAULT;
@@ -1637,12 +1637,13 @@ static int cm_mport_get_list(void __user *arg)
*entry_ptr = (cm->mport->id << 16) |
cm->mport->host_deviceid;
entry_ptr++;
+ copied++;
}
}
up_read(&rdev_sem);
*((u32 *)buf) = count; /* report a real number of entries */
- if (copy_to_user(arg, buf, sizeof(u32) * (count + 1)))
+ if (copy_to_user(arg, buf, sizeof(u32) * (copied + 1)))
ret = -EFAULT;
kfree(buf);
--
2.54.0