]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
firmware: arm_ffa: Validate framework notification message layout
authorSudeep Holla <sudeep.holla@kernel.org>
Tue, 28 Apr 2026 18:33:32 +0000 (19:33 +0100)
committerSudeep Holla <sudeep.holla@kernel.org>
Tue, 5 May 2026 15:42:48 +0000 (16:42 +0100)
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>
drivers/firmware/arm_ffa/driver.c

index d1e70866a425477331284042122b0781a303505d..7287423faceb4beb8a17f8c38ad03d197d03f6b2 100644 (file)
@@ -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);