Skip to content
Snippets Groups Projects
Commit f05fa65a authored by Anjan Chanda's avatar Anjan Chanda
Browse files

validate minimum length of tlvs in cmdu_parse_tlvs()

parent 67ace7d3
Branches
No related tags found
No related merge requests found
......@@ -126,6 +126,7 @@
#define IEEE80211_ROLE_UNKNOWN (0xff)
typedef uint8_t macaddr_t[6];
......
......@@ -126,6 +126,47 @@ uint16_t tlv_total_length(struct tlv *t)
return tlv_length(t) + 3;
}
static size_t tlv_minsize(uint8_t type)
{
size_t sizeof_tlv[] = {
[TLV_TYPE_END_OF_MESSAGE] = sizeof(struct tlv_eom),
[TLV_TYPE_AL_MAC_ADDRESS_TYPE] = sizeof(struct tlv_aladdr),
[TLV_TYPE_MAC_ADDRESS_TYPE] = sizeof(struct tlv_macaddr),
[TLV_TYPE_DEVICE_INFORMATION_TYPE] = sizeof(struct tlv_device_info),
[TLV_TYPE_DEVICE_BRIDGING_CAPABILITIES] = sizeof(struct tlv_device_bridge_caps),
[TLV_TYPE_NON_1905_NEIGHBOR_DEVICE_LIST] = sizeof(struct tlv_non1905_neighbor),
[TLV_TYPE_NEIGHBOR_DEVICE_LIST] = sizeof(struct tlv_1905neighbor),
[TLV_TYPE_LINK_METRIC_QUERY] = sizeof(struct tlv_linkmetric_query),
[TLV_TYPE_TRANSMITTER_LINK_METRIC] = sizeof(struct tlv_tx_linkmetric),
[TLV_TYPE_RECEIVER_LINK_METRIC] = sizeof(struct tlv_rx_linkmetric),
[TLV_TYPE_VENDOR_SPECIFIC] = sizeof(struct tlv_vendor_specific),
[TLV_TYPE_LINK_METRIC_RESULT_CODE] = sizeof(struct tlv_linkmetric_result),
[TLV_TYPE_SEARCHED_ROLE] = sizeof(struct tlv_searched_role),
[TLV_TYPE_AUTOCONFIG_FREQ_BAND] = sizeof(struct tlv_autoconfig_band),
[TLV_TYPE_SUPPORTED_ROLE] = sizeof(struct tlv_supported_role),
[TLV_TYPE_SUPPORTED_FREQ_BAND] = sizeof(struct tlv_supported_band),
[TLV_TYPE_WSC] = sizeof(struct tlv_wsc),
[TLV_TYPE_PUSH_BUTTON_EVENT_NOTIFICATION] = sizeof(struct tlv_pbc_notification),
[TLV_TYPE_PUSH_BUTTON_JOIN_NOTIFICATION] = sizeof(struct tlv_pbc_join_notification),
[TLV_TYPE_GENERIC_PHY_DEVICE_INFORMATION] = sizeof(struct tlv_generic_phy_devinfo),
[TLV_TYPE_DEVICE_IDENTIFICATION] = sizeof(struct tlv_device_identification),
[TLV_TYPE_CONTROL_URL] = sizeof(struct tlv_control_url),
[TLV_TYPE_IPV4] = sizeof(struct tlv_ipv4),
[TLV_TYPE_IPV6] = sizeof(struct tlv_ipv6),
[TLV_TYPE_GENERIC_PHY_EVENT_NOTIFICATION] = sizeof(struct tlv_pbc_generic_phy_notification),
[TLV_TYPE_1905_PROFILE_VERSION] = sizeof(struct tlv_1905_profile),
[TLV_TYPE_POWER_OFF_INTERFACE] = sizeof(struct tlv_power_off),
[TLV_TYPE_INTERFACE_POWER_CHANGE_INFORMATION] = sizeof(struct tlv_powerchange_request),
[TLV_TYPE_INTERFACE_POWER_CHANGE_STATUS] = sizeof(struct tlv_powerchange_status),
[TLV_TYPE_L2_NEIGHBOR_DEVICE] = sizeof(struct tlv_l2_neighbor),
};
if (type >= TLV_TYPE_END_OF_MESSAGE && type <= TLV_TYPE_L2_NEIGHBOR_DEVICE)
return sizeof_tlv[type];
return 0;
}
int is_cmdu_type_valid(uint16_t type)
{
return (type >= CMDU_TYPE_TOPOLOGY_DISCOVERY &&
......@@ -554,6 +595,9 @@ int cmdu_parse_tlv_single(struct cmdu_buff *c, struct tlv *tv[],
if (policy->maxlen > 0 && tlv_length(t) > policy->maxlen)
continue;
if (tlv_length(t) < tlv_minsize(t))
continue;
if (tv[0] && policy->present == TLV_PRESENT_ONE)
break;
......@@ -598,6 +642,9 @@ int cmdu_parse_tlvs(struct cmdu_buff *c, struct tlv *tv[][16],
tlv_length(t) > policy[i].maxlen)
continue;
if (tlv_length(t) < tlv_minsize(t))
continue;
if (tv[i][0]) {
if (policy[i].present == TLV_PRESENT_ONE)
continue;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment