| From f8f84af5da9ee04ef1d271528656dac42a090d00 Mon Sep 17 00:00:00 2001 |
| From: Alexander Larkin <avlarkin82@gmail.com> |
| Date: Sun, 4 Jul 2021 22:39:36 -0700 |
| Subject: Input: joydev - prevent use of not validated data in JSIOCSBTNMAP ioctl |
| |
| From: Alexander Larkin <avlarkin82@gmail.com> |
| |
| commit f8f84af5da9ee04ef1d271528656dac42a090d00 upstream. |
| |
| Even though we validate user-provided inputs we then traverse past |
| validated data when applying the new map. The issue was originally |
| discovered by Murray McAllister with this simple POC (if the following |
| is executed by an unprivileged user it will instantly panic the system): |
| |
| int main(void) { |
| int fd, ret; |
| unsigned int buffer[10000]; |
| |
| fd = open("/dev/input/js0", O_RDONLY); |
| if (fd == -1) |
| printf("Error opening file\n"); |
| |
| ret = ioctl(fd, JSIOCSBTNMAP & ~IOCSIZE_MASK, &buffer); |
| printf("%d\n", ret); |
| } |
| |
| The solution is to traverse internal buffer which is guaranteed to only |
| contain valid date when constructing the map. |
| |
| Fixes: 182d679b2298 ("Input: joydev - prevent potential read overflow in ioctl") |
| Fixes: 999b874f4aa3 ("Input: joydev - validate axis/button maps before clobbering current ones") |
| Reported-by: Murray McAllister <murray.mcallister@gmail.com> |
| Suggested-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Alexander Larkin <avlarkin82@gmail.com> |
| Link: https://lore.kernel.org/r/20210620120030.1513655-1-avlarkin82@gmail.com |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/input/joydev.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/drivers/input/joydev.c |
| +++ b/drivers/input/joydev.c |
| @@ -500,7 +500,7 @@ static int joydev_handle_JSIOCSBTNMAP(st |
| memcpy(joydev->keypam, keypam, len); |
| |
| for (i = 0; i < joydev->nkey; i++) |
| - joydev->keymap[keypam[i] - BTN_MISC] = i; |
| + joydev->keymap[joydev->keypam[i] - BTN_MISC] = i; |
| |
| out: |
| kfree(keypam); |