瀏覽代碼

qcacld-3.0: Acquire read lock before accessing the address list

This is a qcacld-2.0 to qcacld-3.0 propagation.

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
Srinivas Girigowda 8 年之前
父節點
當前提交
90cdd3cda2
共有 1 個文件被更改,包括 12 次插入2 次删除
  1. 12 2
      core/hdd/src/wlan_hdd_power.c

+ 12 - 2
core/hdd/src/wlan_hdd_power.c

@@ -304,9 +304,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;
@@ -326,6 +329,8 @@ static int hdd_fill_ipv6_uc_addr(struct inet6_dev *idev,
 			hdd_err("The Scope %d is not supported", scope);
 		}
 	}
+
+	read_unlock_bh(&idev->lock);
 	return 0;
 }
 
@@ -347,9 +352,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) {
@@ -367,6 +375,8 @@ static int hdd_fill_ipv6_ac_addr(struct inet6_dev *idev,
 			hdd_err("The Scope %d is not supported", scope);
 		}
 	}
+
+	read_unlock_bh(&idev->lock);
 	return 0;
 }