ソースを参照

qcacld-3.0: Fix memory corruption due to wlan_hdd_add_age_ie

In wlan_hdd_add_age_ie the mgmt->u.probe_resp.variable is type casted
to qcom_ie_age, before incrementing the mgmt->u.probe_resp.variable
to get the qcom_ie_age pointer. This leads to memory corruption.

Fixed by typecasting the pointer once the qcom_ie_age pointer is
derived by incrementing the offset of qcom_ie_age from
mgmt->u.probe_resp.variable.

Change-Id: Iafcdb5c17f0d9c234687ddcc6f8b9100b21cc957
CRs-Fixed: 2201303
Abhishek Singh 7 年 前
コミット
f1c1676351
1 ファイル変更6 行追加6 行削除
  1. 6 6
      core/hdd/src/wlan_hdd_cfg80211.c

+ 6 - 6
core/hdd/src/wlan_hdd_cfg80211.c

@@ -16232,7 +16232,7 @@ wlan_hdd_get_frame_len(struct bss_description *bss_desc)
 }
 
 static inline void wlan_hdd_add_age_ie(struct ieee80211_mgmt *mgmt,
-	uint32_t ie_length, struct bss_description *bss_desc)
+	uint32_t *ie_length, struct bss_description *bss_desc)
 {
 	qcom_ie_age *qie_age = NULL;
 
@@ -16240,8 +16240,8 @@ static inline void wlan_hdd_add_age_ie(struct ieee80211_mgmt *mgmt,
 	 * GPS Requirement: need age ie per entry. Using vendor specific.
 	 * Assuming this is the last IE, copy at the end
 	 */
-	ie_length -= sizeof(qcom_ie_age);
-	qie_age = (qcom_ie_age *)mgmt->u.probe_resp.variable + ie_length;
+	*ie_length -= sizeof(qcom_ie_age);
+	qie_age = (qcom_ie_age *)(mgmt->u.probe_resp.variable + *ie_length);
 	qie_age->element_id = QCOM_VENDOR_IE_ID;
 	qie_age->len = QCOM_VENDOR_IE_AGE_LEN;
 	qie_age->oui_1 = QCOM_OUI1;
@@ -16269,7 +16269,7 @@ wlan_hdd_get_frame_len(struct bss_description *bss_desc)
 	return GET_IE_LEN_IN_BSS(bss_desc->length);
 }
 static inline void wlan_hdd_add_age_ie(struct ieee80211_mgmt *mgmt,
-	uint32_t ie_length, struct bss_description *bss_desc)
+	uint32_t *ie_length, struct bss_description *bss_desc)
 {
 }
 #endif /* WLAN_ENABLE_AGEIE_ON_SCAN_RESULTS */
@@ -16281,7 +16281,7 @@ wlan_hdd_inform_bss_frame(struct hdd_adapter *adapter,
 {
 	struct wireless_dev *wdev = adapter->dev->ieee80211_ptr;
 	struct wiphy *wiphy = wdev->wiphy;
-	int ie_length = wlan_hdd_get_frame_len(bss_desc);
+	uint32_t ie_length = wlan_hdd_get_frame_len(bss_desc);
 	const char *ie =
 		((ie_length != 0) ? (const char *)&bss_desc->ieFields : NULL);
 	uint32_t freq, i;
@@ -16334,7 +16334,7 @@ wlan_hdd_inform_bss_frame(struct hdd_adapter *adapter,
 	bss_data.mgmt->u.probe_resp.beacon_int = bss_desc->beaconInterval;
 	bss_data.mgmt->u.probe_resp.capab_info = bss_desc->capabilityInfo;
 
-	wlan_hdd_add_age_ie(bss_data.mgmt, ie_length, bss_desc);
+	wlan_hdd_add_age_ie(bss_data.mgmt, &ie_length, bss_desc);
 
 	memcpy(bss_data.mgmt->u.probe_resp.variable, ie, ie_length);
 	if (bss_desc->fProbeRsp) {