hcidump: Add assoc dump function assoc date length check
PATCH 1/1 hcidump: Add assoc dump function assoc date length check
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(-)
tools/parser/amp.c +27 -8
@@ -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 ; } }
tools/parser/hci.c +2 -2
@@ -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 ); } }
tools/parser/l2cap.c +4 -2
@@ -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)
tools/parser/parser.h +1 -1
@@ -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) {
Signature · 1 line
2.21.0