All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Cho, Yu-Chen" <acho@suse.com>
To: linux-bluetooth@vger.kernel.org
Cc: acho@suse.com, jlee@suse.com
Subject: [PATCH] hcidump: Add assoc dump function assoc date length check
Date: Tue, 19 Mar 2019 16:59:58 +0800	[thread overview]
Message-ID: <20190319085958.6544-1-acho@suse.com> (raw)

amp_assoc_dump() didn't check the length of amp assoc struct.
If there is wrong lengh size of assoc date, amp_assoc_dump() and
amp_dump_chanlist() will read over the size(heap-buffer-overflow).

use t_len to save the length avoid use the wrong size of date.
---
 tools/parser/amp.c    | 35 +++++++++++++++++++++++++++--------
 tools/parser/hci.c    |  4 ++--
 tools/parser/l2cap.c  |  6 ++++--
 tools/parser/parser.h |  2 +-
 4 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/tools/parser/amp.c b/tools/parser/amp.c
index 7c85fb96c..d3459dfe1 100644
--- a/tools/parser/amp.c
+++ b/tools/parser/amp.c
@@ -28,7 +28,8 @@
 #include "parser.h"
 #include "lib/amp.h"
 
-static void amp_dump_chanlist(int level, struct amp_tlv *tlv, char *prefix)
+static void amp_dump_chanlist(int level, struct amp_tlv *tlv,
+			      uint16_t t_len, char *prefix)
 {
 	struct amp_chan_list *chan_list = (void *) tlv->val;
 	struct amp_country_triplet *triplet;
@@ -38,6 +39,12 @@ static void amp_dump_chanlist(int level, struct amp_tlv *tlv, char *prefix)
 
 	printf("%s (number of triplets %d)\n", prefix, num);
 
+	if (btohs(tlv->len) > t_len) {
+		p_indent(level+1, 0);
+		printf("Wrong number of triplets\n");
+		num = (t_len - sizeof(*chan_list)) / sizeof(*triplet);
+	}
+
 	p_indent(level+2, 0);
 
 	printf("Country code: %c%c%c\n", chan_list->country_code[0],
@@ -68,7 +75,7 @@ static void amp_dump_chanlist(int level, struct amp_tlv *tlv, char *prefix)
 	}
 }
 
-void amp_assoc_dump(int level, uint8_t *assoc, uint16_t len)
+void amp_assoc_dump(int level, uint8_t *assoc, uint16_t len, uint16_t t_len)
 {
 	struct amp_tlv *tlv = (void *) assoc;
 
@@ -76,6 +83,14 @@ void amp_assoc_dump(int level, uint8_t *assoc, uint16_t len)
 	printf("Assoc data [len %d]:\n", len);
 
 	while (len > sizeof(*tlv)) {
+		if (btohs(tlv->len) > (t_len - sizeof(struct amp_tlv))) {
+			p_indent(level+1, 0);
+			printf("Assoc data get error size\n");
+			t_len -= sizeof(struct amp_tlv);
+		} else {
+			t_len -= sizeof(struct amp_tlv) + btohs(tlv->len);
+		}
+
 		uint16_t tlvlen = btohs(tlv->len);
 		struct amp_pal_ver *ver;
 
@@ -91,11 +106,13 @@ void amp_assoc_dump(int level, uint8_t *assoc, uint16_t len)
 			break;
 
 		case A2MP_PREF_CHANLIST_TYPE:
-			amp_dump_chanlist(level, tlv, "Preferred Chan List");
+			amp_dump_chanlist(level, tlv,
+					  t_len, "Preferred Chan List");
 			break;
 
 		case A2MP_CONNECTED_CHAN:
-			amp_dump_chanlist(level, tlv, "Connected Chan List");
+			amp_dump_chanlist(level, tlv,
+					  t_len, "Connected Chan List");
 			break;
 
 		case A2MP_PAL_CAP_TYPE:
@@ -119,9 +136,11 @@ void amp_assoc_dump(int level, uint8_t *assoc, uint16_t len)
 			printf("Unrecognized type %d\n", tlv->type);
 			break;
 		}
-
-		len -= tlvlen + sizeof(*tlv);
-		assoc += tlvlen + sizeof(*tlv);
-		tlv = (struct amp_tlv *) assoc;
+		if (btohs(tlv->len) <= t_len) {
+			len -= tlvlen + sizeof(*tlv);
+			assoc += tlvlen + sizeof(*tlv);
+			tlv = (struct amp_tlv *) assoc;
+		} else
+			len = 0;
 	}
 }
diff --git a/tools/parser/hci.c b/tools/parser/hci.c
index 41f6fe087..424ff4bd7 100644
--- a/tools/parser/hci.c
+++ b/tools/parser/hci.c
@@ -1679,7 +1679,7 @@ static inline void write_remote_amp_assoc_cmd_dump(int level,
 	printf("handle 0x%2.2x len_so_far %d remaining_len %d\n", cp->handle,
 				cp->length_so_far, cp->remaining_length);
 
-	amp_assoc_dump(level + 1, cp->fragment, frm->len - 5);
+	amp_assoc_dump(level + 1, cp->fragment, frm->len - 5, frm->len - 5);
 }
 
 static inline void command_dump(int level, struct frame *frm)
@@ -2662,7 +2662,7 @@ static inline void read_local_amp_assoc_dump(int level, struct frame *frm)
 		p_indent(level, frm);
 		printf("Error: %s\n", status2str(rp->status));
 	} else {
-		amp_assoc_dump(level + 1, rp->fragment, len);
+		amp_assoc_dump(level + 1, rp->fragment, len, frm->len - 4);
 	}
 }
 
diff --git a/tools/parser/l2cap.c b/tools/parser/l2cap.c
index e43761cf7..58a23a54c 100644
--- a/tools/parser/l2cap.c
+++ b/tools/parser/l2cap.c
@@ -1172,7 +1172,8 @@ static inline void a2mp_assoc_rsp(int level, struct frame *frm, uint16_t len)
 
 	printf("Get AMP Assoc rsp: id %d status (%d) %s\n",
 			h->id, h->status, a2mpstatus2str(h->status));
-	amp_assoc_dump(level + 1, h->assoc_data, len - sizeof(*h));
+	amp_assoc_dump(level + 1, h->assoc_data,
+		       len - sizeof(*h), frm->len - sizeof(*h));
 }
 
 static inline void a2mp_create_req(int level, struct frame *frm, uint16_t len)
@@ -1181,7 +1182,8 @@ static inline void a2mp_create_req(int level, struct frame *frm, uint16_t len)
 
 	printf("Create Physical Link req: local id %d remote id %d\n",
 		   h->local_id, h->remote_id);
-	amp_assoc_dump(level + 1, h->assoc_data, len - sizeof(*h));
+	amp_assoc_dump(level + 1, h->assoc_data,
+		       len - sizeof(*h), frm->len - sizeof(*h));
 }
 
 static inline void a2mp_create_rsp(int level, struct frame *frm)
diff --git a/tools/parser/parser.h b/tools/parser/parser.h
index b7e1d7568..97c4bbea1 100644
--- a/tools/parser/parser.h
+++ b/tools/parser/parser.h
@@ -249,7 +249,7 @@ void ericsson_dump(int level, struct frame *frm);
 void csr_dump(int level, struct frame *frm);
 void bpa_dump(int level, struct frame *frm);
 
-void amp_assoc_dump(int level, uint8_t *assoc, uint16_t len);
+void amp_assoc_dump(int level, uint8_t *assoc, uint16_t len, uint16_t t_len);
 
 static inline void parse(struct frame *frm)
 {
-- 
2.21.0


                 reply	other threads:[~2019-03-19  9:00 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20190319085958.6544-1-acho@suse.com \
    --to=acho@suse.com \
    --cc=jlee@suse.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.