DivestOS/Patches/Linux_CVEs/CVE-2016-8419/1.patch

103 lines
4.4 KiB
Diff

From 5dcbbf80f4deb9b078cca860f6d1760d6f9398b8 Mon Sep 17 00:00:00 2001
From: Srinivas Girigowda <sgirigow@codeaurora.org>
Date: Wed, 9 Nov 2016 13:54:57 -0800
Subject: [PATCH] qcacld-2.0: Properly parse PNO vendor command
Currently there is a single wlan_hdd_extscan_config_policy which
contains entries for both EXTSCAN and PNO attributes. However the
EXTSCAN and PNO attributes have separate and overlapping
assignments. Therefore one policy cannot be used by both types of
commands. In addition, when parsing nested PNO attributes the policy
is not used, and hence no checking is performed on the nested
data. This can result in a buffer overflow.
To address these issues introduce a new policy for PNO vendor
commands, and use that policy both when parsing the initial command
and when parsing the nested attributes.
Change-Id: I92c8fc7ca1c44971502ea68b5486a2b3ae941cc5
CRs-Fixed: 1087209
Bug: 32454494
Signed-off-by: Srinivas Girigowda <sgirigow@codeaurora.org>
---
.../qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c | 39 ++++++++++++++--------
1 file changed, 25 insertions(+), 14 deletions(-)
diff --git a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c
index ae8d13dd85b29..29f388fc7433f 100644
--- a/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/drivers/staging/qcacld-2.0/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -842,11 +842,6 @@ wlan_hdd_extscan_config_policy[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_
[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_LOST_AP_SAMPLE_SIZE] = { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_MIN_BREACHING] = { .type = NLA_U32 },
[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP] = { .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 },
- [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_EXTSCAN_SSID_THRESHOLD_PARAM_SSID] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_SSID_LEN + 1 },
[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SSID_HOTLIST_PARAMS_LOST_SSID_SAMPLE_SIZE] = { .type = NLA_U32 },
@@ -858,6 +853,23 @@ 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
+ },
+};
+
+static const struct nla_policy
wlan_hdd_extscan_results_policy[QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_MAX + 1] =
{
[QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_SCAN_RESULT_BEACON_PERIOD] = { .type = NLA_U16 },
@@ -4675,19 +4687,18 @@ static int hdd_extscan_epno_fill_network_list(
struct wifi_epno_params *req_msg,
struct nlattr **tb)
{
- struct nlattr *network[
- QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX + 1];
+ struct nlattr *network[QCA_WLAN_VENDOR_ATTR_PNO_MAX + 1];
struct nlattr *networks;
int rem1, ssid_len;
uint8_t index, *ssid;
index = 0;
nla_for_each_nested(networks,
- tb[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST],
- rem1) {
- if (nla_parse(network,
- QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
- nla_data(networks), nla_len(networks), NULL)) {
+ tb[QCA_WLAN_VENDOR_ATTR_PNO_SET_LIST_PARAM_EPNO_NETWORKS_LIST],
+ rem1) {
+ if (nla_parse(network, QCA_WLAN_VENDOR_ATTR_PNO_MAX,
+ nla_data(networks), nla_len(networks),
+ wlan_hdd_pno_config_policy)) {
hddLog(LOGE, FL("nla_parse failed"));
return -EINVAL;
}
@@ -4774,8 +4785,8 @@ static int __wlan_hdd_cfg80211_set_epno_list(struct wiphy *wiphy,
}
if (nla_parse(tb, QCA_WLAN_VENDOR_ATTR_PNO_MAX,
- data, data_len,
- wlan_hdd_extscan_config_policy)) {
+ data, data_len,
+ wlan_hdd_pno_config_policy)) {
hddLog(LOGE, FL("Invalid ATTR"));
return -EINVAL;
}