]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
Input: aiptek - validate raw macro indices before updating state
authorPengpeng Hou <pengpeng@iscas.ac.cn>
Tue, 7 Apr 2026 04:52:34 +0000 (21:52 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Tue, 7 Apr 2026 05:10:55 +0000 (22:10 -0700)
aiptek_irq() derives macro key indices directly from tablet reports and
then uses them to index macroKeyEvents[]. Report types 4 and 5 also save
the derived value in aiptek->lastMacro and later use that state to
release the previous key.

Validate the raw macro index once before it enters that state machine, so
lastMacro only ever stores an in-range macro key. Keep direct bounds
checks for report type 6, which reads the macro number from the packet
body and uses it immediately.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260329001711.88076-1-pengpeng@iscas.ac.cn
[dtor: fix macro fallback in report 5s to use -1]
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/tablet/aiptek.c

index 1ad3c19aa155debd7608301f4ad3c694d52d0b24..c850b5890070617c0d197370e85ed8318a1776f5 100644 (file)
@@ -657,6 +657,8 @@ static void aiptek_irq(struct urb *urb)
                pck = (data[1] & aiptek->curSetting.stylusButtonUpper) != 0 ? 1 : 0;
 
                macro = dv && p && tip && !(data[3] & 1) ? (data[3] >> 1) : -1;
+               if (macro >= ARRAY_SIZE(macroKeyEvents))
+                       macro = -1;
                z = get_unaligned_le16(data + 4);
 
                if (dv) {
@@ -698,7 +700,9 @@ static void aiptek_irq(struct urb *urb)
                left = (data[1]& aiptek->curSetting.mouseButtonLeft) != 0 ? 1 : 0;
                right = (data[1] & aiptek->curSetting.mouseButtonRight) != 0 ? 1 : 0;
                middle = (data[1] & aiptek->curSetting.mouseButtonMiddle) != 0 ? 1 : 0;
-               macro = dv && p && left && !(data[3] & 1) ? (data[3] >> 1) : 0;
+               macro = dv && p && left && !(data[3] & 1) ? (data[3] >> 1) : -1;
+               if (macro >= ARRAY_SIZE(macroKeyEvents))
+                       macro = -1;
 
                if (dv) {
                        /* If the selected tool changed, reset the old
@@ -736,11 +740,11 @@ static void aiptek_irq(struct urb *urb)
         */
        else if (data[0] == 6) {
                macro = get_unaligned_le16(data + 1);
-               if (macro > 0) {
+               if (macro > 0 && macro - 1 < ARRAY_SIZE(macroKeyEvents)) {
                        input_report_key(inputdev, macroKeyEvents[macro - 1],
                                         0);
                }
-               if (macro < 25) {
+               if (macro + 1 < ARRAY_SIZE(macroKeyEvents)) {
                        input_report_key(inputdev, macroKeyEvents[macro + 1],
                                         0);
                }
@@ -759,7 +763,8 @@ static void aiptek_irq(struct urb *urb)
                                aiptek->curSetting.toolMode;
                }
 
-               input_report_key(inputdev, macroKeyEvents[macro], 1);
+               if (macro < ARRAY_SIZE(macroKeyEvents))
+                       input_report_key(inputdev, macroKeyEvents[macro], 1);
                input_report_abs(inputdev, ABS_MISC,
                                 1 | AIPTEK_REPORT_TOOL_UNKNOWN);
                input_sync(inputdev);