]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
Input: hynitron_cstxxx - validate touch count and finger IDs
authorJianing Li <m13940358460@163.com>
Tue, 4 Aug 2026 04:18:52 +0000 (21:18 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Tue, 4 Aug 2026 04:51:42 +0000 (21:51 -0700)
The driver allocates max_touch_num input slots, which are indexed from
zero through max_touch_num - 1. The current check allows a finger ID
equal to max_touch_num to reach cst3xx_report_contact(). While the input
core ignores out-of-range slot indices, reporting touch data without a
valid slot change corrupts the touch state of the previously active slot.

The touch count is read from the controller's report and is used to
index the fixed-size report buffer without first checking its range.
Reject counts larger than the supported number of touch slots before
checking the trailing byte or parsing touch data.

Reject finger IDs equal to or greater than max_touch_num, and return
immediately when an invalid finger ID is encountered so that corrupt
touch frames are discarded instead of reporting partial contact state.

The V821 Avaota F1 board configures the vendor driver with one touch
slot, so finger ID 1 is already invalid on that device.

Fixes: 66603243f528 ("Input: add driver for Hynitron cstxxx touchscreens")
Signed-off-by: Jianing Li <m13940358460@163.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260804031339.2379-1-m13940358460@163.com
Assisted-by: Antigravity:gemini-3.6-flash
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/touchscreen/hynitron_cstxxx.c

index 1d8ca90dcda695bc7bbd6f486db974ab7fb49530..af66d91848b3005deb23b57d2142e66ade77aa26 100644 (file)
@@ -313,6 +313,12 @@ static void cst3xx_touch_report(struct i2c_client *client)
                return;
 
        touch_cnt = buf[5] & CST3XX_TOUCH_COUNT_MASK;
+       if (touch_cnt > ts_data->chip->max_touch_num) {
+               dev_err(&client->dev, "cst3xx invalid touch count (%d vs %d max)\n",
+                       touch_cnt, ts_data->chip->max_touch_num);
+               return;
+       }
+
        /*
         * Check the check bit of the last touch slot. The check bit is
         * always present after touch point 1 for valid data, and then
@@ -335,9 +341,10 @@ static void cst3xx_touch_report(struct i2c_client *client)
                finger_id = (buf[idx] >> 4) & 0x0f;
 
                /* Sanity check we don't have more fingers than we expect */
-               if (ts_data->chip->max_touch_num < finger_id) {
-                       dev_err(&client->dev, "cst3xx touch read failure\n");
-                       break;
+               if (finger_id >= ts_data->chip->max_touch_num) {
+                       dev_err(&client->dev,
+                               "cst3xx invalid finger id %d\n", finger_id);
+                       return;
                }
 
                /* sw value of 0 means no touch, 0x03 means touch */