From 00241c31cbde567c9b7b76a00700abb8051e984b Mon Sep 17 00:00:00 2001
From: Mohit Aggarwal <maggarwa@codeaurora.org>
Date: Thu, 2 Jun 2016 15:04:32 -0700
Subject: [PATCH] diag: Fix possible underflow/overflow issues

Add check in order to fix possible integer underflow
during HDLC encoding which may lead to buffer
overflow. Also added check for packet length to
avoid buffer overflow.

Bug: 28767796
Change-Id: I6dfe890c9db521c9144f05155c50b289c83b5b8f
Signed-off-by: Mohit Aggarwal <maggarwa@codeaurora.org>
Signed-off-by: Yuan Lin <yualin@google.com>
---
 drivers/char/diag/diagfwd.c | 13 +++++++++++++
 drivers/char/diag/diagfwd.h |  2 +-
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 62f63a7699ae..7e68176f1212 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -1679,6 +1679,19 @@ void diag_process_hdlc(void *data, unsigned len)
 	hdlc.escaping = 0;
 
 	ret = diag_hdlc_decode(&hdlc);
+
+	/*
+	 * If the message is 3 bytes or less in length then the message is
+	 * too short. A message will need 4 bytes minimum, since there are
+	 * 2 bytes for the CRC and 1 byte for the ending 0x7e for the hdlc
+	 * encoding
+	 */
+	if (hdlc.dest_idx < 4) {
+		pr_err_ratelimited("diag: In %s, message is too short, len: %d,"
+			" dest len: %d\n", __func__, len, hdlc.dest_idx);
+		mutex_unlock(&driver->diag_hdlc_mutex);
+		return;
+	}
 	if (ret) {
 		crc_chk = crc_check(hdlc.dest_ptr, hdlc.dest_idx);
 		if (crc_chk) {
diff --git a/drivers/char/diag/diagfwd.h b/drivers/char/diag/diagfwd.h
index d3018030cdd7..e6532d516b64 100644
--- a/drivers/char/diag/diagfwd.h
+++ b/drivers/char/diag/diagfwd.h
@@ -20,7 +20,7 @@
 #define RESET_AND_QUEUE 1
 
 #define CHK_OVERFLOW(bufStart, start, end, length) \
-	((((bufStart) <= (start)) && ((end) - (start) >= (length))) ? 1 : 0)
+  ((((bufStart) <= (start)) && ((end) - (start) >= (length)) && ((length) > 0)) ? 1 : 0)
 
 void diagfwd_init(void);
 void diagfwd_exit(void);
-- 
GitLab