mailbox: riscv-sbi-mpxy: validate RPMI notification lengths

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: bf3022a4eb ("mailbox: Add RISC-V SBI message proxy (MPXY) based mailbox driver")
Assisted-by: Codex:gpt-5
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Signed-off-by: Jassi Brar <jassisinghbrar@gmail.com>
This commit is contained in:
Pengpeng Hou
2026-08-14 16:02:15 +08:00
committed by Jassi Brar
parent 3ccffcc367
commit 11d5af151b

View File

@@ -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;