83 lines
2.8 KiB
Diff
83 lines
2.8 KiB
Diff
From: Grant Hernandez <granthernandez@google.com>
|
|
Date: Sat, 13 Jul 2019 01:00:12 -0700
|
|
Subject: Input: gtco - bounds check collection indent level
|
|
Origin: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=d657077eda7b5572d86f2f618391bb016b5d9a64
|
|
Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2019-13631
|
|
|
|
commit 2a017fd82c5402b3c8df5e3d6e5165d9e6147dc1 upstream.
|
|
|
|
The GTCO tablet input driver configures itself from an HID report sent
|
|
via USB during the initial enumeration process. Some debugging messages
|
|
are generated during the parsing. A debugging message indentation
|
|
counter is not bounds checked, leading to the ability for a specially
|
|
crafted HID report to cause '-' and null bytes be written past the end
|
|
of the indentation array. As long as the kernel has CONFIG_DYNAMIC_DEBUG
|
|
enabled, this code will not be optimized out. This was discovered
|
|
during code review after a previous syzkaller bug was found in this
|
|
driver.
|
|
|
|
Signed-off-by: Grant Hernandez <granthernandez@google.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/tablet/gtco.c | 20 +++++++++++++++++---
|
|
1 file changed, 17 insertions(+), 3 deletions(-)
|
|
|
|
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c
|
|
index 4b8b9d7aa75e..35031228a6d0 100644
|
|
--- a/drivers/input/tablet/gtco.c
|
|
+++ b/drivers/input/tablet/gtco.c
|
|
@@ -78,6 +78,7 @@ Scott Hill shill@gtcocalcomp.com
|
|
|
|
/* Max size of a single report */
|
|
#define REPORT_MAX_SIZE 10
|
|
+#define MAX_COLLECTION_LEVELS 10
|
|
|
|
|
|
/* Bitmask whether pen is in range */
|
|
@@ -223,8 +224,7 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report,
|
|
char maintype = 'x';
|
|
char globtype[12];
|
|
int indent = 0;
|
|
- char indentstr[10] = "";
|
|
-
|
|
+ char indentstr[MAX_COLLECTION_LEVELS + 1] = { 0 };
|
|
|
|
dev_dbg(ddev, "======>>>>>>PARSE<<<<<<======\n");
|
|
|
|
@@ -350,6 +350,13 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report,
|
|
case TAG_MAIN_COL_START:
|
|
maintype = 'S';
|
|
|
|
+ if (indent == MAX_COLLECTION_LEVELS) {
|
|
+ dev_err(ddev, "Collection level %d would exceed limit of %d\n",
|
|
+ indent + 1,
|
|
+ MAX_COLLECTION_LEVELS);
|
|
+ break;
|
|
+ }
|
|
+
|
|
if (data == 0) {
|
|
dev_dbg(ddev, "======>>>>>> Physical\n");
|
|
strcpy(globtype, "Physical");
|
|
@@ -369,8 +376,15 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report,
|
|
break;
|
|
|
|
case TAG_MAIN_COL_END:
|
|
- dev_dbg(ddev, "<<<<<<======\n");
|
|
maintype = 'E';
|
|
+
|
|
+ if (indent == 0) {
|
|
+ dev_err(ddev, "Collection level already at zero\n");
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ dev_dbg(ddev, "<<<<<<======\n");
|
|
+
|
|
indent--;
|
|
for (x = 0; x < indent; x++)
|
|
indentstr[x] = '-';
|
|
--
|
|
cgit 1.2-0.3.lf.el7
|
|
|