diff --git a/src/cntlr_map.c b/src/cntlr_map.c index 5a7e65db4340464cf5c7f6a840ce5fc8ea46a1c9..218148a928d4381cd5b38a11edbc50a27bebd30a 100644 --- a/src/cntlr_map.c +++ b/src/cntlr_map.c @@ -958,13 +958,24 @@ int handle_channel_pref_report(void *cntlr, struct cmdu_buff *cmdu) idx = 0; while (tv[0][idx]) { - struct tlv *t = (struct tlv *)tv[0][idx++]; + struct tlv *t; + uint16_t t_len; uint8_t mac[6] = { 0 }; int num_opclass; + t = (struct tlv *) tv[0][idx]; + t_len = tlv_length(tv[0][idx]); + idx++; + offset = 0; + + if (WARN_ON(offset + 6 > t_len)) + continue; memcpy(mac, &t->data[offset], 6); offset += 6; + + if (WARN_ON(offset + 1 > t_len)) + continue; num_opclass = t->data[offset++]; radio = find_radio_by_node(cntlr, node, mac); @@ -980,8 +991,13 @@ int handle_channel_pref_report(void *cntlr, struct cmdu_buff *cmdu) uint8_t preference; uint8_t channel; + if (WARN_ON(offset + 2 > t_len)) + break; opclass = t->data[offset++]; num_channel = t->data[offset++]; + + if (WARN_ON(offset + num_channel + 1 > t_len)) + break; preference = t->data[offset + num_channel]; for (j = 0; j < num_channel; j++) {