[PATCH v2] mailbox: riscv-sbi-mpxy: validate RPMI notification lengths
Pengpeng Hou
pengpeng at iscas.ac.cn
Fri Aug 14 01:02:15 PDT 2026
The SBI return value controls how many bytes are copied from shared
memory into the RPMI notification buffer. It is not validated against
the negotiated shared-memory size before that copy. The event walker
also uses a reversed loop condition and can inspect a short event record.
Validate the complete notification length before copying it, iterate only
while a full event header remains, and stop when a declared event payload
extends beyond the copied notification data.
Fixes: bf3022a4eb11 ("mailbox: Add RISC-V SBI message proxy (MPXY) based mailbox driver")
Assisted-by: Codex:gpt-5
Signed-off-by: Pengpeng Hou <pengpeng at iscas.ac.cn>
---
Changes since v1: https://lore.kernel.org/all/20260706092108.78340-1-pengpeng@iscas.ac.cn/
- validate the SBI-reported total before copying shared memory
- fix the inverted full-event-header loop condition
- validate each event payload extent before dispatch
The shared-memory and event extents were reviewed statically; malformed
RPMI firmware data was not injected.
drivers/mailbox/riscv-sbi-mpxy-mbox.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/mailbox/riscv-sbi-mpxy-mbox.c b/drivers/mailbox/riscv-sbi-mpxy-mbox.c
index 7c9c006b7244..714f7fb97a2f 100644
--- a/drivers/mailbox/riscv-sbi-mpxy-mbox.c
+++ b/drivers/mailbox/riscv-sbi-mpxy-mbox.c
@@ -314,8 +314,13 @@ static int mpxy_get_notifications(u32 channel_id,
channel_id, 0, 0, 0, 0, 0);
if (sret.error)
goto err_put_cpu;
+ if (sret.value < 0 || mpxy_shmem_size < sizeof(*notif_data) ||
+ sret.value > mpxy_shmem_size - sizeof(*notif_data)) {
+ put_cpu();
+ return -EOVERFLOW;
+ }
- memcpy(notif_data, mpxy->shmem, sret.value + 16);
+ memcpy(notif_data, mpxy->shmem, sret.value + sizeof(*notif_data));
*events_data_len = sret.value;
err_put_cpu:
@@ -480,11 +485,14 @@ static void mpxy_mbox_peek_rpmi_data(struct mbox_chan *chan,
struct rpmi_mbox_message msg;
unsigned long pos = 0;
- while (pos < events_data_len && (events_data_len - pos) <= sizeof(*event)) {
+ while (events_data_len - pos >= sizeof(*event)) {
event = (struct rpmi_notification_event *)(notif->events_data + pos);
msg.type = RPMI_MBOX_MSG_TYPE_NOTIFICATION_EVENT;
msg.notif.event_datalen = le16_to_cpu(event->event_datalen);
+ if (msg.notif.event_datalen >
+ events_data_len - pos - sizeof(*event))
+ break;
msg.notif.event_id = event->event_id;
msg.notif.event_data = event->event_data;
msg.error = 0;
--
2.50.1 (Apple Git-155)
More information about the linux-riscv
mailing list