summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Larkin <avlarkin82@gmail.com>2021-07-05 08:39:36 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2021-07-20 17:17:28 +0300
commit0f3e884a746ad9a1038f9c85ef983a4dfbee0d8e (patch)
tree5239f5422cf172328935e08933acd60304c5f56e
parent1ff545051fb76c29efd82f0bece107cc5ba6a9bb (diff)
downloadlinux-0f3e884a746ad9a1038f9c85ef983a4dfbee0d8e.tar.xz
Input: joydev - prevent use of not validated data in JSIOCSBTNMAP ioctl
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>
-rw-r--r--drivers/input/joydev.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
index 48e6e5df9859..0e70bc711e7d 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -504,7 +504,7 @@ static int joydev_handle_JSIOCSBTNMAP(struct joydev *joydev,
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);