]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Input: synaptics-rmi4 - zero report size on F54 work error
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Fri, 26 Jun 2026 05:17:51 +0000 (22:17 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Wed, 5 Aug 2026 04:16:51 +0000 (21:16 -0700)
In rmi_f54_work(), if an error occurs during report request or command
verification, the code jumped directly to the 'error' label, bypassing
the 'abort' label where f54->report_size was normally zeroed out.

This left f54->report_size containing its previous successful payload
size. If a user then altered the V4L2 format to a smaller size, and a
subsequent run failed, rmi_f54_buffer_queue() would copy the stale,
larger payload size into the shrunken V4L2 buffer, causing a heap
buffer overflow.

Fix this by merging the 'abort' and 'error' labels into a single 'out'
exit path, and ensuring that f54->report_size is always set to 0 on
failure by checking for error and zeroing the local report_size first.

Fixes: 3a762dbd5347 ("[media] Input: synaptics-rmi4 - add support for F54 diagnostics")
Cc: stable@vger.kernel.org
Reported-by: sashiko-bot@kernel.org
Assisted-by: Antigravity:gemini-3.5-flash
Link: https://patch.msgid.link/20260626051802.4033172-2-dmitry.torokhov@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/rmi4/rmi_f54.c

index 61909e1a39e248729c2f5c7e33788b0d69919c10..8eac320c43e35ce37b6d5a61d2138bc8c6a9e278 100644 (file)
@@ -545,7 +545,7 @@ static void rmi_f54_work(struct work_struct *work)
                dev_err(&fn->dev, "Bad report size, report type=%d\n",
                                f54->report_type);
                error = -EINVAL;
-               goto error;     /* retry won't help */
+               goto out;     /* retry won't help */
        }
 
        /*
@@ -556,7 +556,7 @@ static void rmi_f54_work(struct work_struct *work)
                         &command);
        if (error) {
                dev_err(&fn->dev, "Failed to read back command\n");
-               goto error;
+               goto out;
        }
        if (command & F54_GET_REPORT) {
                if (time_after(jiffies, f54->timeout)) {
@@ -564,7 +564,7 @@ static void rmi_f54_work(struct work_struct *work)
                        error = -ETIMEDOUT;
                }
                report_size = 0;
-               goto error;
+               goto out;
        }
 
        rmi_dbg(RMI_DEBUG_FN, &fn->dev, "Get report command completed, reading data\n");
@@ -579,7 +579,7 @@ static void rmi_f54_work(struct work_struct *work)
                                        fifo, sizeof(fifo));
                if (error) {
                        dev_err(&fn->dev, "Failed to set fifo start offset\n");
-                       goto abort;
+                       goto out;
                }
 
                error = rmi_read_block(fn->rmi_dev, fn->fd.data_base_addr +
@@ -588,16 +588,16 @@ static void rmi_f54_work(struct work_struct *work)
                if (error) {
                        dev_err(&fn->dev, "%s: read [%d bytes] returned %d\n",
                                __func__, size, error);
-                       goto abort;
+                       goto out;
                }
        }
 
-abort:
-       f54->report_size = error ? 0 : report_size;
-error:
+out:
        if (error)
                report_size = 0;
 
+       f54->report_size = report_size;
+
        if (report_size == 0 && !error) {
                queue_delayed_work(f54->workqueue, &f54->work,
                                   msecs_to_jiffies(1));