summaryrefslogtreecommitdiff
path: root/drivers/firmware/arm_ffa
diff options
context:
space:
mode:
authorSudeep Holla <sudeep.holla@kernel.org>2026-04-28 19:33:32 +0100
committerSudeep Holla <sudeep.holla@kernel.org>2026-05-05 16:42:48 +0100
commit4a1cc9e96b311d2609a6f963a5e35bd4ae730d97 (patch)
tree87594a9d3f4153a24bf3391fa0f91eba2cb1ab61 /drivers/firmware/arm_ffa
parent2af18f8e36b277730527cacc2256b1332f56aa28 (diff)
firmware: arm_ffa: Validate framework notification message layout
Framework notifications carry an indirect message in the shared RX buffer. Validate the reported offset and size before using them, reject zero-length payloads, and ensure that any non-header payload starts at the UUID field rather than in the middle of the message header. Use the validated offset and size values for both kmemdup() and the UUID parsing path so malformed firmware data cannot drive an out-of-bounds read or an oversized allocation. Fixes: 285a5ea0f542 ("firmware: arm_ffa: Add support for handling framework notifications") Link: https://patch.msgid.link/20260428-ffa_fixes-v2-8-8595ae450034@kernel.org Signed-off-by: Sudeep Holla <sudeep.holla@kernel.org>
Diffstat (limited to 'drivers/firmware/arm_ffa')
-rw-r--r--drivers/firmware/arm_ffa/driver.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/firmware/arm_ffa/driver.c b/drivers/firmware/arm_ffa/driver.c
index d1e70866a425..7287423faceb 100644
--- a/drivers/firmware/arm_ffa/driver.c
+++ b/drivers/firmware/arm_ffa/driver.c
@@ -1487,21 +1487,35 @@ static void handle_fwk_notif_callbacks(u32 bitmap)
int notify_id = 0, target;
struct ffa_indirect_msg_hdr *msg;
struct notifier_cb_info *cb_info = NULL;
+ size_t min_offset = offsetof(struct ffa_indirect_msg_hdr, uuid);
/* Only one framework notification defined and supported for now */
if (!(bitmap & FRAMEWORK_NOTIFY_RX_BUFFER_FULL))
return;
scoped_guard(mutex, &drv_info->rx_lock) {
+ u32 offset, size;
+
msg = drv_info->rx_buffer;
- buf = kmemdup((void *)msg + msg->offset, msg->size, GFP_KERNEL);
+ offset = msg->offset;
+ size = msg->size;
+
+ if (!size || (offset != min_offset && offset < sizeof(*msg)) ||
+ offset > drv_info->rxtx_bufsz ||
+ size > drv_info->rxtx_bufsz - offset) {
+ pr_err("invalid framework notification message\n");
+ ffa_rx_release();
+ return;
+ }
+
+ buf = kmemdup((void *)msg + offset, size, GFP_KERNEL);
if (!buf) {
ffa_rx_release();
return;
}
target = SENDER_ID(msg->send_recv_id);
- if (msg->offset >= sizeof(*msg))
+ if (offset >= sizeof(*msg))
uuid_copy(&uuid, &msg->uuid);
else
uuid_copy(&uuid, &uuid_null);