summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSrinivas Girigowda <sgirigow@qca.qualcomm.com>2016-08-01 18:14:12 -0700
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-08-02 14:28:54 +0530
commit9fc2af2f07a2d65553728b66ecbf26c315c993ed (patch)
treeff17f40512e6c53a31610fa6a5f1d7933c3fa04e
parent61a56bfb334a746c3ecd66e983608c019119b93d (diff)
qcacld-2.0: Acquire read lock before accessing the address list
WLAN host driver access the inet6_dev address list without acquiring the read lock, if the kernel network stack deletes the address while driver is accessing the list, it can lead to referencing already freed address by the driver. Hence, fix is to take the read lock before accessing the address list. Change-Id: I934e9f2039f3ab8540e439b9e8a87efced98807c CRs-Fixed: 1048897
-rw-r--r--CORE/HDD/src/wlan_hdd_early_suspend.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c
index 0bc33eb7e8c3..222ab88b0b13 100644
--- a/CORE/HDD/src/wlan_hdd_early_suspend.c
+++ b/CORE/HDD/src/wlan_hdd_early_suspend.c
@@ -654,9 +654,12 @@ static int hdd_fill_ipv6_uc_addr(struct inet6_dev *idev,
struct list_head *p;
uint32_t scope;
+ read_lock_bh(&idev->lock);
list_for_each(p, &idev->addr_list) {
- if (*count >= SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA)
+ if (*count >= SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA) {
+ read_unlock_bh(&idev->lock);
return -EINVAL;
+ }
ifa = list_entry(p, struct inet6_ifaddr, if_list);
if (ifa->flags & IFA_F_DADFAILED)
continue;
@@ -677,6 +680,8 @@ static int hdd_fill_ipv6_uc_addr(struct inet6_dev *idev,
hddLog(LOGE, "The Scope %d is not supported", scope);
}
}
+
+ read_unlock_bh(&idev->lock);
return 0;
}
@@ -698,9 +703,12 @@ static int hdd_fill_ipv6_ac_addr(struct inet6_dev *idev,
struct ifacaddr6 *ifaca;
uint32_t scope;
+ read_lock_bh(&idev->lock);
for (ifaca = idev->ac_list; ifaca; ifaca = ifaca->aca_next) {
- if (*count >= SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA)
+ if (*count >= SIR_MAC_NUM_TARGET_IPV6_NS_OFFLOAD_NA) {
+ read_unlock_bh(&idev->lock);
return -EINVAL;
+ }
/* For anycast addr no DAD */
scope = ipv6_addr_src_scope(&ifaca->aca_addr);
switch (scope) {
@@ -719,6 +727,8 @@ static int hdd_fill_ipv6_ac_addr(struct inet6_dev *idev,
hddLog(LOGE, "The Scope %d is not supported", scope);
}
}
+
+ read_unlock_bh(&idev->lock);
return 0;
}