Jeremy Cline 3d5a0b4
From c9fcba15565f3db7232489366c87c298c4198b0a Mon Sep 17 00:00:00 2001
Jeremy Cline 3d5a0b4
From: Grant Hernandez <granthernandez@google.com>
Jeremy Cline 3d5a0b4
Date: Thu, 11 Jul 2019 15:22:32 -0700
Jeremy Cline 3d5a0b4
Subject: [PATCH] Input: gtco - bounds check collection indent level
Jeremy Cline 3d5a0b4
Jeremy Cline 3d5a0b4
The GTCO tablet input driver configures itself from an HID report sent
Jeremy Cline 3d5a0b4
via USB during the initial enumeration process. Some debugging messages
Jeremy Cline 3d5a0b4
are generated during the parsing. A debugging message indentation
Jeremy Cline 3d5a0b4
counter is not bounds checked, leading to the ability for a specially
Jeremy Cline 3d5a0b4
crafted HID report to cause '-' and null bytes be written past the end
Jeremy Cline 3d5a0b4
of the indentation array. As long as the kernel has CONFIG_DYNAMIC_DEBUG
Jeremy Cline 3d5a0b4
enabled, this code will not be optimized out.  This was discovered
Jeremy Cline 3d5a0b4
during code review after a previous syzkaller bug was found in this
Jeremy Cline 3d5a0b4
driver.
Jeremy Cline 3d5a0b4
Jeremy Cline 3d5a0b4
Cc: stable@vger.kernel.org
Jeremy Cline 3d5a0b4
Signed-off-by: Grant Hernandez <granthernandez@google.com>
Jeremy Cline 3d5a0b4
---
Jeremy Cline 3d5a0b4
 drivers/input/tablet/gtco.c | 19 ++++++++++++++++---
Jeremy Cline 3d5a0b4
 1 file changed, 16 insertions(+), 3 deletions(-)
Jeremy Cline 3d5a0b4
Jeremy Cline 3d5a0b4
diff --git a/drivers/input/tablet/gtco.c b/drivers/input/tablet/gtco.c
Jeremy Cline 3d5a0b4
index 4b8b9d7aa75e..9771052ed027 100644
Jeremy Cline 3d5a0b4
--- a/drivers/input/tablet/gtco.c
Jeremy Cline 3d5a0b4
+++ b/drivers/input/tablet/gtco.c
Jeremy Cline 3d5a0b4
@@ -78,6 +78,7 @@ Scott Hill shill@gtcocalcomp.com
Jeremy Cline 3d5a0b4
 
Jeremy Cline 3d5a0b4
 /* Max size of a single report */
Jeremy Cline 3d5a0b4
 #define REPORT_MAX_SIZE       10
Jeremy Cline 3d5a0b4
+#define MAX_COLLECTION_LEVELS  10
Jeremy Cline 3d5a0b4
 
Jeremy Cline 3d5a0b4
 
Jeremy Cline 3d5a0b4
 /* Bitmask whether pen is in range */
Jeremy Cline 3d5a0b4
@@ -223,8 +224,7 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report,
Jeremy Cline 3d5a0b4
 	char  maintype = 'x';
Jeremy Cline 3d5a0b4
 	char  globtype[12];
Jeremy Cline 3d5a0b4
 	int   indent = 0;
Jeremy Cline 3d5a0b4
-	char  indentstr[10] = "";
Jeremy Cline 3d5a0b4
-
Jeremy Cline 3d5a0b4
+	char  indentstr[MAX_COLLECTION_LEVELS+1] = {0};
Jeremy Cline 3d5a0b4
 
Jeremy Cline 3d5a0b4
 	dev_dbg(ddev, "======>>>>>>PARSE<<<<<<======\n");
Jeremy Cline 3d5a0b4
 
Jeremy Cline 3d5a0b4
@@ -350,6 +350,12 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report,
Jeremy Cline 3d5a0b4
 			case TAG_MAIN_COL_START:
Jeremy Cline 3d5a0b4
 				maintype = 'S';
Jeremy Cline 3d5a0b4
 
Jeremy Cline 3d5a0b4
+				if (indent == MAX_COLLECTION_LEVELS) {
Jeremy Cline 3d5a0b4
+					dev_err(ddev, "Collection level %d would exceed limit of %d\n",
Jeremy Cline 3d5a0b4
+						indent+1, MAX_COLLECTION_LEVELS);
Jeremy Cline 3d5a0b4
+					break;
Jeremy Cline 3d5a0b4
+				}
Jeremy Cline 3d5a0b4
+
Jeremy Cline 3d5a0b4
 				if (data == 0) {
Jeremy Cline 3d5a0b4
 					dev_dbg(ddev, "======>>>>>> Physical\n");
Jeremy Cline 3d5a0b4
 					strcpy(globtype, "Physical");
Jeremy Cline 3d5a0b4
@@ -369,8 +375,15 @@ static void parse_hid_report_descriptor(struct gtco *device, char * report,
Jeremy Cline 3d5a0b4
 				break;
Jeremy Cline 3d5a0b4
 
Jeremy Cline 3d5a0b4
 			case TAG_MAIN_COL_END:
Jeremy Cline 3d5a0b4
-				dev_dbg(ddev, "<<<<<<======\n");
Jeremy Cline 3d5a0b4
 				maintype = 'E';
Jeremy Cline 3d5a0b4
+
Jeremy Cline 3d5a0b4
+				if (indent == 0) {
Jeremy Cline 3d5a0b4
+					dev_err(ddev, "Collection level already at zero\n");
Jeremy Cline 3d5a0b4
+					break;
Jeremy Cline 3d5a0b4
+				}
Jeremy Cline 3d5a0b4
+
Jeremy Cline 3d5a0b4
+				dev_dbg(ddev, "<<<<<<======\n");
Jeremy Cline 3d5a0b4
+
Jeremy Cline 3d5a0b4
 				indent--;
Jeremy Cline 3d5a0b4
 				for (x = 0; x < indent; x++)
Jeremy Cline 3d5a0b4
 					indentstr[x] = '-';
Jeremy Cline 3d5a0b4
-- 
Jeremy Cline 3d5a0b4
2.21.0
Jeremy Cline 3d5a0b4