summaryrefslogtreecommitdiffstats
path: root/drivers/input
diff options
context:
space:
mode:
authorAlexander Larkin <avlarkin82@gmail.com>2021-07-04 22:39:36 -0700
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2021-07-04 23:02:10 -0700
commitf8f84af5da9ee04ef1d271528656dac42a090d00 (patch)
tree255e5a9ec541325f48e45c60168ad36fe6a140da /drivers/input
parentcac7100d4c51c04979dacdfe6c9a5e400d3f0a27 (diff)
downloadlinux-f8f84af5da9ee04ef1d271528656dac42a090d00.tar.bz2
Input: joydev - prevent use of not validated data in JSIOCSBTNMAP ioctl
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>
Diffstat (limited to 'drivers/input')
-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 da8963a9f044..947d440a3be6 100644
--- a/drivers/input/joydev.c
+++ b/drivers/input/joydev.c
@@ -499,7 +499,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);