[PATCH v3] Input: tca8418_keypad - fix potential infinite loop and OOB access on invalid keycodes

Zhian Liang <[email protected]>
Newsgroups org.kernel.vger.linux-input,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
If the hardware returns 0xFF (e.g., due to a stuck bus or device fault), the loop never terminates and
the extracted keycode causes an out-of-bounds access on keymap[].

Move the empty-FIFO check to operate on the extracted key code so that
the loop terminates correctly. Additionally, validate row/column indices
against the configured matrix dimensions before indexing into the
keymap array, skipping invalid events.

Cc: [email protected]
Signed-off-by: Zhian Liang <[email protected]>
---
changes in v2:
- Moved empty-FIFO check to operate on extracted key code instead of
  raw register value.
- Added row/col validation against configured matrix dimensions.
- Dropped explicit 0xFF check as requested.
---
changes in v3:
-Fix mailer line-wrapping
-No code changes
Signed-off-by: Zhian Liang <[email protected]>
---
 drivers/input/keyboard/tca8418_keypad.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c
index b124e576feca..36d4a7c38bb1 100644
--- a/drivers/input/keyboard/tca8418_keypad.c
+++ b/drivers/input/keyboard/tca8418_keypad.c
@@ -114,6 +114,8 @@ struct tca8418_keypad {
 	struct input_dev *input;
 
 	unsigned int row_shift;
+	unsigned int rows;
+	unsigned int cols;
 };
 
 /*
@@ -171,19 +173,28 @@ static void tca8418_read_keypad(struct tca8418_keypad *keypad_data)
 			break;
 		}
 
-		/* Assume that key code 0 signifies empty FIFO */
-		if (reg <= 0)
-			break;
 
 		state = reg & KEY_EVENT_VALUE;
 		code  = reg & KEY_EVENT_CODE;
 
+		/* Key code 0 signifies empty FIFO */
+		if (!code)
+			break;
+
 		row = code / TCA8418_MAX_COLS;
 		col = code % TCA8418_MAX_COLS;
 
 		row = (col) ? row : row - 1;
 		col = (col) ? col - 1 : TCA8418_MAX_COLS - 1;
 
+		/* Validate against configured matrix size */
+		if (row >= keypad_data->rows || col >= keypad_data->cols) {
+			dev_err(&keypad_data->client->dev,
+				"invalid key code %d (row %d, col %d)\n",
+				code, row, col);
+			continue;
+		}
+
 		code = MATRIX_SCAN_CODE(row, col, keypad_data->row_shift);
 		input_event(input, EV_MSC, MSC_SCAN, code);
 		input_report_key(input, keymap[code], state);
@@ -298,6 +309,8 @@ static int tca8418_keypad_probe(struct i2c_client *client)
 
 	keypad_data->client = client;
 	keypad_data->row_shift = row_shift;
+	keypad_data->rows = rows;
+	keypad_data->cols = cols;
 
 	/* Read key lock register, if this fails assume device not present */
 	error = tca8418_read_byte(keypad_data, REG_KEY_LCK_EC, &reg);
-- 
2.34.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.