From 657bb41463b837b2681e1fed310bd97970b09b83 Mon Sep 17 00:00:00 2001 From: Mukul Sharma Date: Mon, 19 Jun 2017 19:21:42 +0530 Subject: qcacld-2.0: Avoid buffer overread when parsing PNO commands Propagation from qcacld-3.0 to qcacld-2.0 There are currently three issues which can result in a buffer overread when processing PNO vendor commands: 1) __wlan_hdd_cfg80211_set_passpoint_list() specifies the wrong policy when invoking nla_parse(). 2) hdd_extscan_passpoint_fill_network_list() does not specify a policy when invoking nla_parse(). 3) __wlan_hdd_cfg80211_set_epno_list() specifies a policy but not all of the attributes that are parsed are present in the policy. To prevent buffer overread: 1) Update __wlan_hdd_cfg80211_set_passpoint_list() and hdd_extscan_passpoint_fill_network_list() to use the policy wlan_hdd_pno_config_policy. 2) Update wlan_hdd_pno_config_policy to contain all the fixed-length attributes needed by __wlan_hdd_cfg80211_set_passpoint_list(), hdd_extscan_passpoint_fill_network_list(), and __wlan_hdd_cfg80211_set_epno_list(). Change-Id: I4a20e77ce87967ae78323b83a2aa9085fed2647f CRs-Fixed: 2058447 --- CORE/HDD/src/wlan_hdd_cfg80211.c | 58 +++++++++++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index cae8b45..20f127b 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -868,19 +868,46 @@ wlan_hdd_extscan_config_policy[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_ static const struct nla_policy wlan_hdd_pno_config_policy[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1] = { - [QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS] = { - .type = NLA_U32 - }, - [QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID] = { - .type = NLA_BINARY, - .len = IEEE80211_MAX_SSID_LEN + 1 - }, - [QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS] = { - .type = NLA_U8 - }, - [QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT] = { - .type = NLA_U8 - }, + [QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_LIST_PARAM_NUM] = { + .type = NLA_U32 + }, + [QCA_WLAN_VENDOR_ATTR_PNO_PASSPOINT_NETWORK_PARAM_ID] = { + .type = NLA_U32 + }, + [QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_NUM_NETWORKS] = { + .type = NLA_U32 + }, + [QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_SSID] = { + .type = NLA_BINARY, + .len = IEEE80211_MAX_SSID_LEN + 1 + }, + [QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_FLAGS] = { + .type = NLA_U8 + }, + [QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORK_AUTH_BIT] = { + .type = NLA_U8 + }, + [QCA_WLAN_VENDOR_ATTR_EPNO_MIN5GHZ_RSSI] = { + .type = NLA_U32 + }, + [QCA_WLAN_VENDOR_ATTR_EPNO_MIN24GHZ_RSSI] = { + .type = NLA_U32 + }, + [QCA_WLAN_VENDOR_ATTR_EPNO_INITIAL_SCORE_MAX] = { + .type = NLA_U32 + }, + [QCA_WLAN_VENDOR_ATTR_EPNO_CURRENT_CONNECTION_BONUS] = { + .type = NLA_U32 + }, + [QCA_WLAN_VENDOR_ATTR_EPNO_SAME_NETWORK_BONUS] = { + .type = NLA_U32 + }, + [QCA_WLAN_VENDOR_ATTR_EPNO_SECURE_BONUS] = { + .type = NLA_U32 + }, + [QCA_WLAN_VENDOR_ATTR_EPNO_BAND5GHZ_BONUS] = { + .type = NLA_U32 + }, }; static const struct nla_policy @@ -4914,7 +4941,8 @@ static int hdd_extscan_passpoint_fill_network_list( if (nla_parse(network, QCA_WLAN_VENDOR_ATTR_PNO_MAX, - nla_data(networks), nla_len(networks), NULL)) { + nla_data(networks), nla_len(networks), + wlan_hdd_pno_config_policy)) { hddLog(LOGE, FL("nla_parse failed")); return -EINVAL; } @@ -5015,7 +5043,7 @@ static int __wlan_hdd_cfg80211_set_passpoint_list(struct wiphy *wiphy, } if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_PNO_MAX, data, data_len, - wlan_hdd_extscan_config_policy)) { + wlan_hdd_pno_config_policy)) { hddLog(LOGE, FL("Invalid ATTR")); return -EINVAL; } -- cgit v1.1