diag: Fix diag hdlc decoding support for messages starting with 0x7e
Currently, when an hdlc encoded message is processed by diag and it
encounters a 0x7e, it considers that the end of the message. Make changes
to support messages starting with 0x7e.
Also, when a message is encountered that is too short, rate limit the
the associated error message to prevent flooding of messages.
CRs-Fixed: 456952
Change-Id: Ie01387479ca8fb0ae290400b1adc5627faab80d3
Signed-off-by: Dixon Peterson <dixonp@codeaurora.org>
diff --git a/drivers/char/diag/diagchar_hdlc.c b/drivers/char/diag/diagchar_hdlc.c
index b94ea2f..2369c4d 100644
--- a/drivers/char/diag/diagchar_hdlc.c
+++ b/drivers/char/diag/diagchar_hdlc.c
@@ -1,4 +1,5 @@
-/* Copyright (c) 2008-2009, 2012, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2008-2009, 2012-2013, The Linux Foundation.
+ * All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -172,11 +173,14 @@
uint8_t src_byte;
int pkt_bnd = 0;
+ int msg_start;
if (hdlc && hdlc->src_ptr && hdlc->dest_ptr &&
(hdlc->src_size - hdlc->src_idx > 0) &&
(hdlc->dest_size - hdlc->dest_idx > 0)) {
+ msg_start = (hdlc->src_idx == 0) ? 1 : 0;
+
src_ptr = hdlc->src_ptr;
src_ptr = &src_ptr[hdlc->src_idx];
src_length = hdlc->src_size - hdlc->src_idx;
@@ -203,8 +207,16 @@
}
} else if (src_byte == CONTROL_CHAR) {
dest_ptr[len++] = src_byte;
- pkt_bnd = 1;
+ /*
+ * If this is the first byte in the message,
+ * then it is part of the command. Otherwise,
+ * consider it as the last byte of the
+ * message.
+ */
+ if (msg_start && i == 0 && src_length > 1)
+ continue;
i++;
+ pkt_bnd = 1;
break;
} else {
dest_ptr[len++] = src_byte;
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
index 7f4edd1..2aca8cf 100644
--- a/drivers/char/diag/diagfwd.c
+++ b/drivers/char/diag/diagfwd.c
@@ -993,10 +993,18 @@
ret = diag_hdlc_decode(&hdlc);
- if (hdlc.dest_idx < 3) {
- pr_err("diag: Integer underflow in hdlc processing\n");
+ /*
+ * 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);
return;
}
+
if (ret) {
type = diag_process_apps_pkt(driver->hdlc_buf,
hdlc.dest_idx - 3);