Browse Source

qcacld-3.0: malloc enough buffer for stats info

Currently in function hdd_get_station_info, it does not malloc the
NLA_HDRLEN for each attribute, it causes no enough buffer to put
the data.

Since in that function, it combines lots of info for the station,
define WLAN_STATS_INFO_LEN to malloc enough buffer.

Change-Id: I31deccb329c5b14abc97e30ee75de9452f0e06e0
CRs-Fixed: 3325629
Paul Zhang 2 years ago
parent
commit
0d53d82f4f
1 changed files with 12 additions and 53 deletions
  1. 12 53
      core/hdd/src/wlan_hdd_station_info.c

+ 12 - 53
core/hdd/src/wlan_hdd_station_info.c

@@ -143,6 +143,13 @@
 #define ASSOC_REQ_IES \
 	QCA_WLAN_VENDOR_ATTR_GET_STATION_INFO_ASSOC_REQ_IES
 
+/*
+ * it may include the beacon IEs and other miscellaneous information
+ * in function hdd_get_station_info, malloc enough memory to save
+ * the data.
+ */
+#define WLAN_STATS_INFO_LEN 2048
+
 /*
  * MSB of rx_mc_bc_cnt indicates whether FW supports rx_mc_bc_cnt
  * feature or not, if first bit is 1 it indicates that FW supports this
@@ -650,11 +657,6 @@ static int32_t hdd_add_he_oper_info(struct sk_buff *skb,
 	hdd_sta_ctx->cache_conn_info.he_oper_len = 0;
 	return ret;
 }
-
-static int32_t hdd_get_he_op_len(struct hdd_station_ctx *hdd_sta_ctx)
-{
-	return hdd_sta_ctx->cache_conn_info.he_oper_len;
-}
 #else
 static inline uint32_t hdd_add_he_oper_info(
 					struct sk_buff *skb,
@@ -662,19 +664,8 @@ static inline uint32_t hdd_add_he_oper_info(
 {
 	return 0;
 }
-
-static uint32_t hdd_get_he_op_len(struct hdd_station_ctx *hdd_sta_ctx)
-{
-	return 0;
-}
 #endif
 
-static uint32_t hdd_get_prev_connected_bss_ies_len(
-					struct hdd_station_ctx *hdd_sta_ctx)
-{
-	return hdd_sta_ctx->conn_info.prev_ap_bcn_ie.len;
-}
-
 static uint32_t hdd_add_prev_connected_bss_ies(
 					struct sk_buff *skb,
 					struct hdd_station_ctx *hdd_sta_ctx)
@@ -710,7 +701,6 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx,
 {
 	struct sk_buff *skb = NULL;
 	uint8_t *tmp_hs20 = NULL;
-	uint32_t nl_buf_len, hdd_he_op_len = 0;
 	struct hdd_station_ctx *hdd_sta_ctx;
 
 	hdd_sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
@@ -720,41 +710,8 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx,
 		return -EINVAL;
 	}
 
-	nl_buf_len = NLMSG_HDRLEN;
-	nl_buf_len += sizeof(hdd_sta_ctx->
-				cache_conn_info.last_ssid.SSID.length) +
-		      QDF_MAC_ADDR_SIZE +
-		      sizeof(hdd_sta_ctx->cache_conn_info.chan_freq) +
-		      sizeof(hdd_sta_ctx->cache_conn_info.noise) +
-		      sizeof(hdd_sta_ctx->cache_conn_info.signal) +
-		      (sizeof(uint32_t) * 2) +
-		      sizeof(hdd_sta_ctx->cache_conn_info.txrate.nss) +
-		      sizeof(hdd_sta_ctx->cache_conn_info.roam_count) +
-		      sizeof(hdd_sta_ctx->cache_conn_info.last_auth_type) +
-		      sizeof(hdd_sta_ctx->cache_conn_info.dot11mode) +
-		      sizeof(uint32_t);
-	if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_present)
-		nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.vht_caps);
-	if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_present)
-		nl_buf_len += sizeof(hdd_sta_ctx->cache_conn_info.ht_caps);
-	if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
-		tmp_hs20 = (uint8_t *)&(hdd_sta_ctx->
-						cache_conn_info.hs20vendor_ie);
-		nl_buf_len += (sizeof(hdd_sta_ctx->
-					cache_conn_info.hs20vendor_ie) - 1);
-	}
-	if (hdd_sta_ctx->cache_conn_info.conn_flag.ht_op_present)
-		nl_buf_len += sizeof(hdd_sta_ctx->
-						cache_conn_info.ht_operation);
-	if (hdd_sta_ctx->cache_conn_info.conn_flag.vht_op_present)
-		nl_buf_len += sizeof(hdd_sta_ctx->
-						cache_conn_info.vht_operation);
-	nl_buf_len += hdd_get_prev_connected_bss_ies_len(hdd_sta_ctx);
-
-	hdd_he_op_len = hdd_get_he_op_len(hdd_sta_ctx);
-	nl_buf_len += hdd_he_op_len;
-
-	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy, nl_buf_len);
+	skb = cfg80211_vendor_cmd_alloc_reply_skb(hdd_ctx->wiphy,
+						  WLAN_STATS_INFO_LEN);
 	if (!skb) {
 		hdd_err("cfg80211_vendor_cmd_alloc_reply_skb failed");
 		return -ENOMEM;
@@ -813,6 +770,8 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx,
 		goto fail;
 	}
 	if (hdd_sta_ctx->cache_conn_info.conn_flag.hs20_present) {
+		tmp_hs20 =
+			(uint8_t *)&hdd_sta_ctx->cache_conn_info.hs20vendor_ie;
 		if (nla_put(skb, AP_INFO_HS20_INDICATION,
 			    (sizeof(hdd_sta_ctx->cache_conn_info.hs20vendor_ie)
 			     - 1),
@@ -834,7 +793,7 @@ static int hdd_get_station_info(struct hdd_context *hdd_ctx,
 	}
 
 	if (hdd_add_prev_connected_bss_ies(skb, hdd_sta_ctx)) {
-		hdd_err("put fail total buf_len: %u", nl_buf_len);
+		hdd_err("put fail");
 		goto fail;
 	}