* Buffer overrun in the TWL4030 keypad driver with Nokia RX51 @ 2010-07-16 15:28 Laurent Pinchart 2010-07-17 21:37 ` Dmitry Torokhov 0 siblings, 1 reply; 5+ messages in thread From: Laurent Pinchart @ 2010-07-16 15:28 UTC (permalink / raw) To: Dmitry Torokhov, Amit Kucheria; +Cc: linux-input, linux-omap Hi everybody, I've spent the day debugging a kernel crash in the USB networking code to find out the problem was caused by a buffer overrun in the TWL4030 keypad driver. The Nokia RX51 board code (arch/arm/mach-omap2/board-rx51-peripherals.c) defines a key map for the matrix keypad keyboard. The hardware seems to use all of the 8 rows and 8 columns of the keypad, although not all possible locations are used. The TWL4030 supports keypads with at most 8 rows and 8 columns. Most keys are defined with a row and column number between 0 and 7, except KEY(0xff, 2, KEY_F9), KEY(0xff, 4, KEY_F10), KEY(0xff, 5, KEY_F11), The row number is set to 0xff. As the generic matrix keypad support (include/linux/input/matrix_keypad.h) supports at most 16 rows and 16 columns, it masks all but the lower 4 bits of the row and column numbers in the KEY macro. #define MATRIX_MAX_ROWS 16 #define MATRIX_MAX_COLS 16 #define KEY(row, col, val) ((((row) & (MATRIX_MAX_ROWS - 1)) << 24) |\ (((col) & (MATRIX_MAX_COLS - 1)) << 16) |\ (val & 0xffff)) This leads to an effective row number equal to 15. The TWL4030 keypad driver (drivers/input/keyboard/twl4030_keypad.c) allocates in twl4030_kp_probe a 8x8 keycodes map, part of the twl4030_keypad structure. #define TWL4030_MAX_ROWS 8 /* TWL4030 hard limit */ #define TWL4030_MAX_COLS 8 #define TWL4030_ROW_SHIFT 3 #define TWL4030_KEYMAP_SIZE (TWL4030_MAX_ROWS * TWL4030_MAX_COLS) struct twl4030_keypad { unsigned short keymap[TWL4030_KEYMAP_SIZE]; ... It then calls matrix_keypad_build_keymap (include/linux/input/matrix_keypad.h) to initialize the keycodes map from the keymap defined in platform data. The function loops over all the keymap platform data entries, and initializes the corresponding keycodes map entry. The entry index is computed with #define MATRIX_SCAN_CODE(row, col, row_shift) (((row) << (row_shift)) + (col)) called with row_shift set to TWL4030_ROW_SHIFT, defined as 3. For the 3 keys defined with a row equal to 0xff, the map entry index is then equal to (15 << 3) + col, which is bigger than the number of keycodes map entries in the twl4030_keypad structure. Writing to that invalid index overwrites random memory. The 0xff row number is used to detect rows completely connected to ground (see the comment in twl4030_col_xlate, drivers/input/keyboard/twl4030_keypad.c). The related code in twl4030_col_xlate is obviously wrong, returning a column number too large for the allocated keycodes map if the hardware keypad has 8 columns. I can try to provide a patch, but I'm not familiar enough with the TWL4030 keypad driver and the generic matrix keypad code to know what the best fix would be. Hopefully this should be quite clear for the TWL4030 keypad driver developers. -- Regards, Laurent Pinchart ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Buffer overrun in the TWL4030 keypad driver with Nokia RX51 2010-07-16 15:28 Buffer overrun in the TWL4030 keypad driver with Nokia RX51 Laurent Pinchart @ 2010-07-17 21:37 ` Dmitry Torokhov 2010-07-20 11:06 ` Laurent Pinchart 0 siblings, 1 reply; 5+ messages in thread From: Dmitry Torokhov @ 2010-07-17 21:37 UTC (permalink / raw) To: Laurent Pinchart; +Cc: Amit Kucheria, linux-input, linux-omap, Tony Lindgren Hi Laurent. On Fri, Jul 16, 2010 at 05:28:43PM +0200, Laurent Pinchart wrote: > Hi everybody, > > I've spent the day debugging a kernel crash in the USB networking code to find > out the problem was caused by a buffer overrun in the TWL4030 keypad driver. > > The Nokia RX51 board code (arch/arm/mach-omap2/board-rx51-peripherals.c) > defines a key map for the matrix keypad keyboard. The hardware seems to use > all of the 8 rows and 8 columns of the keypad, although not all possible > locations are used. > > The TWL4030 supports keypads with at most 8 rows and 8 columns. Most keys are > defined with a row and column number between 0 and 7, except > > KEY(0xff, 2, KEY_F9), > KEY(0xff, 4, KEY_F10), > KEY(0xff, 5, KEY_F11), > > The row number is set to 0xff. As the generic matrix keypad support > (include/linux/input/matrix_keypad.h) supports at most 16 rows and 16 columns, > it masks all but the lower 4 bits of the row and column numbers in the KEY > macro. [..snipped..] Thanks for the report. Could yo uplease try the patch below and let me know if it works. I have some concerns with the keymap assignments, I see that Amit changed them during KEY(col, row) -> KEY(row, col) conversion. I marked the entries I am concerned with with XXX. Thanks. -- Dmitry Input: twl40300-keypad - fix handling of "all ground" rows From: Dmitry Torokhov <dmitry.torokhov@gmail.com> The Nokia RX51 board code (arch/arm/mach-omap2/board-rx51-peripherals.c) defines a key map for the matrix keypad keyboard. The hardware seems to use all of the 8 rows and 8 columns of the keypad, although not all possible locations are used. The TWL4030 supports keypads with at most 8 rows and 8 columns. Most keys are defined with a row and column number between 0 and 7, except KEY(0xff, 2, KEY_F9), KEY(0xff, 4, KEY_F10), KEY(0xff, 5, KEY_F11), which represent keycodes that should be emitted when entire row is connected to the ground. The driver handles this case as if we had an extra column in the key matrix. Unfortunately we do not allocate enough space and end up owerwriting some random memory. Reported-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru> --- arch/arm/mach-omap2/board-rx51-peripherals.c | 28 ++++++++++++++++++++------ drivers/input/keyboard/twl4030_keypad.c | 17 ++++++++++------ 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-omap2/board-rx51-peripherals.c b/arch/arm/mach-omap2/board-rx51-peripherals.c index abdf321..ea32143 100644 --- a/arch/arm/mach-omap2/board-rx51-peripherals.c +++ b/arch/arm/mach-omap2/board-rx51-peripherals.c @@ -175,6 +175,10 @@ static void __init rx51_add_gpio_keys(void) #endif /* CONFIG_KEYBOARD_GPIO || CONFIG_KEYBOARD_GPIO_MODULE */ static int board_keymap[] = { + /* + * Note that KEY(x, 8, KEY_XXX) entries represent "entire row + * connected to the ground" matrix state. + */ KEY(0, 0, KEY_Q), KEY(0, 1, KEY_O), KEY(0, 2, KEY_P), @@ -182,6 +186,8 @@ static int board_keymap[] = { KEY(0, 4, KEY_BACKSPACE), KEY(0, 6, KEY_A), KEY(0, 7, KEY_S), +// KEY(0, 8, KEY_F6), // XXX was removed + KEY(1, 0, KEY_W), KEY(1, 1, KEY_D), KEY(1, 2, KEY_F), @@ -190,6 +196,8 @@ static int board_keymap[] = { KEY(1, 5, KEY_J), KEY(1, 6, KEY_K), KEY(1, 7, KEY_L), +// KEY(1, 8, KEY_F7), // XXX was moved to (7, 1) + KEY(2, 0, KEY_E), KEY(2, 1, KEY_DOT), KEY(2, 2, KEY_UP), @@ -197,6 +205,8 @@ static int board_keymap[] = { KEY(2, 5, KEY_Z), KEY(2, 6, KEY_X), KEY(2, 7, KEY_C), + KEY(2, 8, KEY_F9), // XXX was F8 and moved to (7, 2), F9 was (4, 8) + KEY(3, 0, KEY_R), KEY(3, 1, KEY_V), KEY(3, 2, KEY_B), @@ -205,20 +215,24 @@ static int board_keymap[] = { KEY(3, 5, KEY_SPACE), KEY(3, 6, KEY_SPACE), KEY(3, 7, KEY_LEFT), + KEY(4, 0, KEY_T), KEY(4, 1, KEY_DOWN), KEY(4, 2, KEY_RIGHT), KEY(4, 4, KEY_LEFTCTRL), - KEY(4, 5, KEY_RIGHTALT), - KEY(4, 6, KEY_LEFTSHIFT), + KEY(4, 5, KEY_RIGHTALT), // XXX was LEFTSHIFT + KEY(4, 6, KEY_LEFTSHIFT), // XXX was FN which is now removed + KEY(4, 8, KEY_10), // XXX was F9 and moved to (2, 8), F10 was (5, 8) + + KEY(5, 0, KEY_Y), + KEY(5, 8, KEY_11), // XXX was F10 and moved to (4, 8), F11 is new + KEY(6, 0, KEY_U), + KEY(7, 0, KEY_I), - KEY(7, 1, KEY_F7), - KEY(7, 2, KEY_F8), - KEY(0xff, 2, KEY_F9), - KEY(0xff, 4, KEY_F10), - KEY(0xff, 5, KEY_F11), + KEY(7, 1, KEY_F7), // XXX was undefined + KEY(7, 2, KEY_F8), // XXX was undefined }; static struct matrix_keymap_data board_map_data = { diff --git a/drivers/input/keyboard/twl4030_keypad.c b/drivers/input/keyboard/twl4030_keypad.c index 7aa59e0..fb16b5e 100644 --- a/drivers/input/keyboard/twl4030_keypad.c +++ b/drivers/input/keyboard/twl4030_keypad.c @@ -51,8 +51,12 @@ */ #define TWL4030_MAX_ROWS 8 /* TWL4030 hard limit */ #define TWL4030_MAX_COLS 8 -#define TWL4030_ROW_SHIFT 3 -#define TWL4030_KEYMAP_SIZE (TWL4030_MAX_ROWS * TWL4030_MAX_COLS) +/* + * Note that we add space for an extra column so that we can handle + * row lines connected to the gnd (see twl4030_col_xlate()). + */ +#define TWL4030_ROW_SHIFT 4 +#define TWL4030_KEYMAP_SIZE (TWL4030_MAX_ROWS << TWL4030_ROW_SHIFT) struct twl4030_keypad { unsigned short keymap[TWL4030_KEYMAP_SIZE]; @@ -182,7 +186,7 @@ static int twl4030_read_kp_matrix_state(struct twl4030_keypad *kp, u16 *state) return ret; } -static int twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state) +static bool twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state) { int i; u16 check = 0; @@ -191,12 +195,12 @@ static int twl4030_is_in_ghost_state(struct twl4030_keypad *kp, u16 *key_state) u16 col = key_state[i]; if ((col & check) && hweight16(col) > 1) - return 1; + return true; check |= col; } - return 0; + return false; } static void twl4030_kp_scan(struct twl4030_keypad *kp, bool release_all) @@ -225,7 +229,8 @@ static void twl4030_kp_scan(struct twl4030_keypad *kp, bool release_all) if (!changed) continue; - for (col = 0; col < kp->n_cols; col++) { + /* Extra column handles "all gnd" rows */ + for (col = 0; col < kp->n_cols + 1; col++) { int code; if (!(changed & (1 << col))) ^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: Buffer overrun in the TWL4030 keypad driver with Nokia RX51 2010-07-17 21:37 ` Dmitry Torokhov @ 2010-07-20 11:06 ` Laurent Pinchart 2010-07-20 18:07 ` Dmitry Torokhov 0 siblings, 1 reply; 5+ messages in thread From: Laurent Pinchart @ 2010-07-20 11:06 UTC (permalink / raw) To: Dmitry Torokhov; +Cc: Amit Kucheria, linux-input, linux-omap, Tony Lindgren Hi Dmitry, On Saturday 17 July 2010 23:37:05 Dmitry Torokhov wrote: > On Fri, Jul 16, 2010 at 05:28:43PM +0200, Laurent Pinchart wrote: > > > > I've spent the day debugging a kernel crash in the USB networking code to > > find out the problem was caused by a buffer overrun in the TWL4030 > > keypad driver. > > > > The Nokia RX51 board code (arch/arm/mach-omap2/board-rx51-peripherals.c) > > defines a key map for the matrix keypad keyboard. The hardware seems to > > use all of the 8 rows and 8 columns of the keypad, although not all > > possible locations are used. > > > > The TWL4030 supports keypads with at most 8 rows and 8 columns. Most keys > > are defined with a row and column number between 0 and 7, except > > > > KEY(0xff, 2, KEY_F9), > > KEY(0xff, 4, KEY_F10), > > KEY(0xff, 5, KEY_F11), > > > > The row number is set to 0xff. As the generic matrix keypad support > > (include/linux/input/matrix_keypad.h) supports at most 16 rows and 16 > > columns, it masks all but the lower 4 bits of the row and column numbers > > in the KEY macro. > > [..snipped..] > > Thanks for the report. Could yo uplease try the patch below and let me > know if it works. The patch fixes the crash at startup, but the F9, F10 and F11 key events are never reported. That might be because those keys are not wired up to anything though. All keys on the keyboard, as well as the F7 and F8 keys (volume up and down on the of the case) generate the proper events. All other "keys" (keyboard slider switch, power button, focus button, lock switch, proximity sensor) report events through other devices. > I have some concerns with the keymap assignments, I see that Amit > changed them during KEY(col, row) -> KEY(row, col) conversion. I marked > the entries I am concerned with with XXX. F7, F8, right alt and left shift are properly mapped. I don't know what F9, F10 and F11 are supposed to be. -- Regards, Laurent Pinchart ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Buffer overrun in the TWL4030 keypad driver with Nokia RX51 2010-07-20 11:06 ` Laurent Pinchart @ 2010-07-20 18:07 ` Dmitry Torokhov 2010-07-21 15:52 ` Laurent Pinchart 0 siblings, 1 reply; 5+ messages in thread From: Dmitry Torokhov @ 2010-07-20 18:07 UTC (permalink / raw) To: Laurent Pinchart; +Cc: Amit Kucheria, linux-input, linux-omap, Tony Lindgren On Tuesday, July 20, 2010 04:06:08 am Laurent Pinchart wrote: > Hi Dmitry, > > On Saturday 17 July 2010 23:37:05 Dmitry Torokhov wrote: > > On Fri, Jul 16, 2010 at 05:28:43PM +0200, Laurent Pinchart wrote: > > > I've spent the day debugging a kernel crash in the USB networking code > > > to find out the problem was caused by a buffer overrun in the TWL4030 > > > keypad driver. > > > > > > The Nokia RX51 board code > > > (arch/arm/mach-omap2/board-rx51-peripherals.c) defines a key map for > > > the matrix keypad keyboard. The hardware seems to use all of the 8 > > > rows and 8 columns of the keypad, although not all possible locations > > > are used. > > > > > > The TWL4030 supports keypads with at most 8 rows and 8 columns. Most > > > keys are defined with a row and column number between 0 and 7, except > > > > > > KEY(0xff, 2, KEY_F9), > > > KEY(0xff, 4, KEY_F10), > > > KEY(0xff, 5, KEY_F11), > > > > > > The row number is set to 0xff. As the generic matrix keypad support > > > (include/linux/input/matrix_keypad.h) supports at most 16 rows and 16 > > > columns, it masks all but the lower 4 bits of the row and column > > > numbers in the KEY macro. > > > > [..snipped..] > > > > Thanks for the report. Could yo uplease try the patch below and let me > > know if it works. > > The patch fixes the crash at startup, Great. > but the F9, F10 and F11 key events > are never reported. That might be because those keys are not wired up to > anything though. I would not know... If you see all keys on the device being handled then I guess it's the case... Tony, Amit, any ideas? > All keys on the keyboard, as well as the F7 and F8 keys > (volume up and down on the of the case) I guess we need to remap them to KEY_VOLUMEUP and KEY_VOLUMEDOWN then. So is F7 == Up and F8 == Down? > generate the proper events. All > other "keys" (keyboard slider switch, power button, focus button, lock > switch, proximity sensor) report events through other devices. > > > I have some concerns with the keymap assignments, I see that Amit > > changed them during KEY(col, row) -> KEY(row, col) conversion. I marked > > the entries I am concerned with with XXX. > > F7, F8, right alt and left shift are properly mapped. I don't know what F9, > F10 and F11 are supposed to be. OK, thanks. Since you don't crash anymore I think it is worth pushing it out. -- Dmitry ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Buffer overrun in the TWL4030 keypad driver with Nokia RX51 2010-07-20 18:07 ` Dmitry Torokhov @ 2010-07-21 15:52 ` Laurent Pinchart 0 siblings, 0 replies; 5+ messages in thread From: Laurent Pinchart @ 2010-07-21 15:52 UTC (permalink / raw) To: Dmitry Torokhov; +Cc: Amit Kucheria, linux-input, linux-omap, Tony Lindgren Hi Dmitry, On Tuesday 20 July 2010 20:07:45 Dmitry Torokhov wrote: > On Tuesday, July 20, 2010 04:06:08 am Laurent Pinchart wrote: > > On Saturday 17 July 2010 23:37:05 Dmitry Torokhov wrote: > > > On Fri, Jul 16, 2010 at 05:28:43PM +0200, Laurent Pinchart wrote: > > > > I've spent the day debugging a kernel crash in the USB networking > > > > code to find out the problem was caused by a buffer overrun in the > > > > TWL4030 keypad driver. > > > > > > > > The Nokia RX51 board code > > > > (arch/arm/mach-omap2/board-rx51-peripherals.c) defines a key map for > > > > the matrix keypad keyboard. The hardware seems to use all of the 8 > > > > rows and 8 columns of the keypad, although not all possible locations > > > > are used. > > > > > > > > The TWL4030 supports keypads with at most 8 rows and 8 columns. Most > > > > keys are defined with a row and column number between 0 and 7, except > > > > > > > > KEY(0xff, 2, KEY_F9), > > > > KEY(0xff, 4, KEY_F10), > > > > KEY(0xff, 5, KEY_F11), > > > > > > > > The row number is set to 0xff. As the generic matrix keypad support > > > > (include/linux/input/matrix_keypad.h) supports at most 16 rows and 16 > > > > columns, it masks all but the lower 4 bits of the row and column > > > > numbers in the KEY macro. > > > > > > [..snipped..] > > > > > > Thanks for the report. Could yo uplease try the patch below and let me > > > know if it works. > > > > The patch fixes the crash at startup, > > Great. > > > but the F9, F10 and F11 key events > > are never reported. That might be because those keys are not wired up to > > anything though. > > I would not know... If you see all keys on the device being handled then I > guess it's the case... Tony, Amit, any ideas? > > > All keys on the keyboard, as well as the F7 and F8 keys > > (volume up and down on the of the case) > > I guess we need to remap them to KEY_VOLUMEUP and KEY_VOLUMEDOWN then. So > is F7 == Up and F8 == Down? It's the other way around. F7 is volume down, F8 is volume up. Note that the same keys have different meanings depending on the context. In the photo viewer, they are used to zoom (volume down zooms out, volume up zooms in). > > generate the proper events. All other "keys" (keyboard slider switch, > > power button, focus button, lock switch, proximity sensor) report events > > through other devices. > > > > > I have some concerns with the keymap assignments, I see that Amit > > > changed them during KEY(col, row) -> KEY(row, col) conversion. I marked > > > the entries I am concerned with with XXX. > > > > F7, F8, right alt and left shift are properly mapped. I don't know what > > F9, F10 and F11 are supposed to be. > > OK, thanks. Since you don't crash anymore I think it is worth pushing > it out. -- Regards, Laurent Pinchart ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2010-07-21 15:52 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2010-07-16 15:28 Buffer overrun in the TWL4030 keypad driver with Nokia RX51 Laurent Pinchart 2010-07-17 21:37 ` Dmitry Torokhov 2010-07-20 11:06 ` Laurent Pinchart 2010-07-20 18:07 ` Dmitry Torokhov 2010-07-21 15:52 ` Laurent Pinchart
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).