Browse Source

qcacmn: Fix out of bound read issue in FILS Indication IE parse

When parsing FILS Indication IE, the data pointer is not
validated while moving the pointer which may cause
out of bound issue.

Validate data pointer before moving pointer.

Change-Id: Ib20f78fe58d7a4c8f9245e6b8d28212499cc6f50
CRs-Fixed: 2842475
Deeksha Gupta 4 năm trước cách đây
mục cha
commit
819a3a5888

+ 10 - 4
umac/scan/core/src/wlan_scan_filter.c

@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
  * any purpose with or without fee is hereby granted, provided that the
@@ -556,6 +556,7 @@ static bool scm_is_fils_config_match(struct scan_filter *filter,
 	int i;
 	int i;
 	struct fils_indication_ie *indication_ie;
 	struct fils_indication_ie *indication_ie;
 	uint8_t *data;
 	uint8_t *data;
+	uint8_t *end_ptr;
 
 
 	if (!filter->fils_scan_filter.realm_check)
 	if (!filter->fils_scan_filter.realm_check)
 		return true;
 		return true;
@@ -566,14 +567,19 @@ static bool scm_is_fils_config_match(struct scan_filter *filter,
 	indication_ie =
 	indication_ie =
 		(struct fils_indication_ie *)db_entry->ie_list.fils_indication;
 		(struct fils_indication_ie *)db_entry->ie_list.fils_indication;
 
 
+	end_ptr = (uint8_t *)indication_ie + indication_ie->len + 2;
 	data = indication_ie->variable_data;
 	data = indication_ie->variable_data;
-	if (indication_ie->is_cache_id_present)
+
+	if (indication_ie->is_cache_id_present &&
+	    (data + CACHE_IDENTIFIER_LEN) < end_ptr)
 		data += CACHE_IDENTIFIER_LEN;
 		data += CACHE_IDENTIFIER_LEN;
 
 
-	if (indication_ie->is_hessid_present)
+	if (indication_ie->is_hessid_present &&
+	    (data + HESSID_LEN) < end_ptr)
 		data += HESSID_LEN;
 		data += HESSID_LEN;
 
 
-	for (i = 1; i <= indication_ie->realm_identifiers_cnt; i++) {
+	for (i = 1; i <= indication_ie->realm_identifiers_cnt &&
+	     (data + REALM_HASH_LEN) < end_ptr; i++) {
 		if (!qdf_mem_cmp(filter->fils_scan_filter.fils_realm,
 		if (!qdf_mem_cmp(filter->fils_scan_filter.fils_realm,
 				 data, REALM_HASH_LEN))
 				 data, REALM_HASH_LEN))
 			return true;
 			return true;