Revert "Revert "[wpa_supplicant] cumilative patch from commit 3a..."

Revert submission 28102966-revert-26533062-Supplicant_merge_June24-CUATTSRBBR

Reason for revert: Fixed the regression issue (ag/28389573)

Reverted changes: /q/submissionid:28102966-revert-26533062-Supplicant_merge_June24-CUATTSRBBR

Bug: 329004037
Test: Turn ON/OFF SoftAp multiple times

Change-Id: Ibfff2a847be5678f1a6d77e28506a05936812a91
diff --git a/src/utils/common.h b/src/utils/common.h
index bede21e..079f90e 100644
--- a/src/utils/common.h
+++ b/src/utils/common.h
@@ -9,6 +9,7 @@
 #ifndef COMMON_H
 #define COMMON_H
 
+#include "includes.h"
 #include "os.h"
 
 #if defined(__linux__) || defined(__GLIBC__)
@@ -441,6 +442,13 @@
 #define BIT(x) (1U << (x))
 #endif
 
+#ifndef MIN
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#endif
+#ifndef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
 /*
  * Definitions for sparse validation
  * (http://kernel.org/pub/linux/kernel/people/josh/sparse/)
@@ -543,6 +551,11 @@
 	return a[0] & 0x01;
 }
 
+static inline bool ether_addr_equal(const u8 *a, const u8 *b)
+{
+	return os_memcmp(a, b, ETH_ALEN) == 0;
+}
+
 #define broadcast_ether_addr (const u8 *) "\xff\xff\xff\xff\xff\xff"
 
 #include "wpa_debug.h"
diff --git a/src/utils/os.h b/src/utils/os.h
index 21ba5c3..1bbaea3 100644
--- a/src/utils/os.h
+++ b/src/utils/os.h
@@ -108,6 +108,26 @@
 }
 
 
+static inline void os_reltime_add_ms(struct os_reltime *ts, int ms)
+{
+	ts->usec += ms * 1000;
+	while (ts->usec >= 1000000) {
+		ts->sec++;
+		ts->usec -= 1000000;
+	}
+	while (ts->usec < 0) {
+		ts->sec--;
+		ts->usec += 1000000;
+	}
+}
+
+
+static inline int os_reltime_in_ms(struct os_reltime *ts)
+{
+	return ts->sec * 1000 + ts->usec / 1000;
+}
+
+
 static inline int os_reltime_initialized(struct os_reltime *t)
 {
 	return t->sec != 0 || t->usec != 0;
@@ -667,14 +687,24 @@
 
 
 #if defined(WPA_TRACE_BFD) && defined(CONFIG_TESTING_OPTIONS)
-#define TEST_FAIL() testing_test_fail()
-int testing_test_fail(void);
-extern char wpa_trace_fail_func[256];
-extern unsigned int wpa_trace_fail_after;
-extern char wpa_trace_test_fail_func[256];
-extern unsigned int wpa_trace_test_fail_after;
+#define TEST_FAIL() testing_test_fail(NULL, false)
+#define TEST_FAIL_TAG(tag) testing_test_fail(tag, false)
+int testing_test_fail(const char *tag, bool is_alloc);
+int testing_set_fail_pattern(bool is_alloc, char *patterns);
+int testing_get_fail_pattern(bool is_alloc, char *buf, size_t buflen);
 #else
 #define TEST_FAIL() 0
+#define TEST_FAIL_TAG(tag) 0
+static inline int testing_set_fail_pattern(bool is_alloc, char *patterns)
+{
+	return -1;
+}
+
+static inline int testing_get_fail_pattern(bool is_alloc, char *buf,
+					   size_t buflen)
+{
+	return -1;
+}
 #endif
 
 #endif /* OS_H */
diff --git a/src/utils/os_unix.c b/src/utils/os_unix.c
index e721df2..e5b656a 100644
--- a/src/utils/os_unix.c
+++ b/src/utils/os_unix.c
@@ -566,39 +566,59 @@
 #ifdef WPA_TRACE
 
 #if defined(WPA_TRACE_BFD) && defined(CONFIG_TESTING_OPTIONS)
-char wpa_trace_fail_func[256] = { 0 };
-unsigned int wpa_trace_fail_after;
+struct wpa_trace_test_fail {
+	unsigned int fail_after;
+	char pattern[256];
+} wpa_trace_test_fail[5][2];
 
-static int testing_fail_alloc(void)
+int testing_test_fail(const char *tag, bool is_alloc)
 {
+	const char *ignore_list[] = {
+		"os_malloc", "os_zalloc", "os_calloc", "os_realloc",
+		"os_realloc_array", "os_strdup", "os_memdup"
+	};
 	const char *func[WPA_TRACE_LEN];
-	size_t i, res, len;
+	size_t i, j, res, len, idx;
 	char *pos, *next;
 	int match;
 
-	if (!wpa_trace_fail_after)
+	is_alloc = !!is_alloc;
+
+	for (idx = 0; idx < ARRAY_SIZE(wpa_trace_test_fail[is_alloc]); idx++) {
+		if (wpa_trace_test_fail[is_alloc][idx].fail_after != 0)
+			break;
+	}
+	if (idx >= ARRAY_SIZE(wpa_trace_test_fail[is_alloc]))
 		return 0;
 
 	res = wpa_trace_calling_func(func, WPA_TRACE_LEN);
 	i = 0;
-	if (i < res && os_strcmp(func[i], __func__) == 0)
-		i++;
-	if (i < res && os_strcmp(func[i], "os_malloc") == 0)
-		i++;
-	if (i < res && os_strcmp(func[i], "os_zalloc") == 0)
-		i++;
-	if (i < res && os_strcmp(func[i], "os_calloc") == 0)
-		i++;
-	if (i < res && os_strcmp(func[i], "os_realloc") == 0)
-		i++;
-	if (i < res && os_strcmp(func[i], "os_realloc_array") == 0)
-		i++;
-	if (i < res && os_strcmp(func[i], "os_strdup") == 0)
-		i++;
-	if (i < res && os_strcmp(func[i], "os_memdup") == 0)
+
+	if (is_alloc) {
+		/* Skip our own stack frame */
 		i++;
 
-	pos = wpa_trace_fail_func;
+		/* Skip allocation helpers */
+		for (j = 0; j < ARRAY_SIZE(ignore_list) && i < res; j++) {
+			if (os_strcmp(func[i], ignore_list[j]) == 0)
+				i++;
+		}
+	} else {
+		/* Not allocation, we might have a tag, if so, replace our
+		 * own stack frame with the tag, otherwise skip it.
+		 */
+		if (tag)
+			func[0] = tag;
+		else
+			i++;
+	}
+
+	pos = wpa_trace_test_fail[is_alloc][idx].pattern;
+
+	/* The prefixes mean:
+	 * - '=': The function needs to be next in the backtrace
+	 * - '?': The function is optionally present in the backtrace
+	 */
 
 	match = 0;
 	while (i < res) {
@@ -638,82 +658,10 @@
 	if (!match)
 		return 0;
 
-	wpa_trace_fail_after--;
-	if (wpa_trace_fail_after == 0) {
-		wpa_printf(MSG_INFO, "TESTING: fail allocation at %s",
-			   wpa_trace_fail_func);
-		for (i = 0; i < res; i++)
-			wpa_printf(MSG_INFO, "backtrace[%d] = %s",
-				   (int) i, func[i]);
-		return 1;
-	}
-
-	return 0;
-}
-
-
-char wpa_trace_test_fail_func[256] = { 0 };
-unsigned int wpa_trace_test_fail_after;
-
-int testing_test_fail(void)
-{
-	const char *func[WPA_TRACE_LEN];
-	size_t i, res, len;
-	char *pos, *next;
-	int match;
-
-	if (!wpa_trace_test_fail_after)
-		return 0;
-
-	res = wpa_trace_calling_func(func, WPA_TRACE_LEN);
-	i = 0;
-	if (i < res && os_strcmp(func[i], __func__) == 0)
-		i++;
-
-	pos = wpa_trace_test_fail_func;
-
-	match = 0;
-	while (i < res) {
-		int allow_skip = 1;
-		int maybe = 0;
-
-		if (*pos == '=') {
-			allow_skip = 0;
-			pos++;
-		} else if (*pos == '?') {
-			maybe = 1;
-			pos++;
-		}
-		next = os_strchr(pos, ';');
-		if (next)
-			len = next - pos;
-		else
-			len = os_strlen(pos);
-		if (os_memcmp(pos, func[i], len) != 0) {
-			if (maybe && next) {
-				pos = next + 1;
-				continue;
-			}
-			if (allow_skip) {
-				i++;
-				continue;
-			}
-			return 0;
-		}
-		if (!next) {
-			match = 1;
-			break;
-		}
-		pos = next + 1;
-		i++;
-	}
-	if (!match)
-		return 0;
-
-	wpa_trace_test_fail_after--;
-	if (wpa_trace_test_fail_after == 0) {
+	wpa_trace_test_fail[is_alloc][idx].fail_after--;
+	if (wpa_trace_test_fail[is_alloc][idx].fail_after == 0) {
 		wpa_printf(MSG_INFO, "TESTING: fail at %s",
-			   wpa_trace_test_fail_func);
+			   wpa_trace_test_fail[is_alloc][idx].pattern);
 		for (i = 0; i < res; i++)
 			wpa_printf(MSG_INFO, "backtrace[%d] = %s",
 				   (int) i, func[i]);
@@ -723,19 +671,84 @@
 	return 0;
 }
 
-#else
 
-static inline int testing_fail_alloc(void)
+int testing_set_fail_pattern(bool is_alloc, char *patterns)
+{
+#ifdef WPA_TRACE_BFD
+	char *token, *context = NULL;
+	size_t idx;
+
+	is_alloc = !!is_alloc;
+
+	os_memset(wpa_trace_test_fail[is_alloc], 0,
+		  sizeof(wpa_trace_test_fail[is_alloc]));
+
+	idx = 0;
+	while ((token = str_token(patterns, " \n\r\t", &context)) &&
+	       idx < ARRAY_SIZE(wpa_trace_test_fail[is_alloc])) {
+		wpa_trace_test_fail[is_alloc][idx].fail_after = atoi(token);
+		token = os_strchr(token, ':');
+		if (!token) {
+			os_memset(wpa_trace_test_fail[is_alloc], 0,
+				  sizeof(wpa_trace_test_fail[is_alloc]));
+			return -1;
+		}
+
+		os_strlcpy(wpa_trace_test_fail[is_alloc][idx].pattern,
+			   token + 1,
+			   sizeof(wpa_trace_test_fail[is_alloc][0].pattern));
+		idx++;
+	}
+
+	return 0;
+#else /* WPA_TRACE_BFD */
+	return -1;
+#endif /* WPA_TRACE_BFD */
+}
+
+
+int testing_get_fail_pattern(bool is_alloc, char *buf, size_t buflen)
+{
+#ifdef WPA_TRACE_BFD
+	size_t idx, ret;
+	char *pos = buf;
+	char *end = buf + buflen;
+
+	is_alloc = !!is_alloc;
+
+	for (idx = 0; idx < ARRAY_SIZE(wpa_trace_test_fail[is_alloc]); idx++) {
+		if (wpa_trace_test_fail[is_alloc][idx].pattern[0] == '\0')
+			break;
+
+		ret = os_snprintf(pos, end - pos, "%s%u:%s",
+				  pos == buf ? "" : " ",
+				  wpa_trace_test_fail[is_alloc][idx].fail_after,
+				  wpa_trace_test_fail[is_alloc][idx].pattern);
+		if (os_snprintf_error(end - pos, ret))
+			break;
+		pos += ret;
+	}
+
+	return pos - buf;
+#else /* WPA_TRACE_BFD */
+	return -1;
+#endif /* WPA_TRACE_BFD */
+}
+
+#else /* defined(WPA_TRACE_BFD) && defined(CONFIG_TESTING_OPTIONS) */
+
+static inline int testing_test_fail(const char *tag, bool is_alloc)
 {
 	return 0;
 }
+
 #endif
 
 void * os_malloc(size_t size)
 {
 	struct os_alloc_trace *a;
 
-	if (testing_fail_alloc())
+	if (testing_test_fail(NULL, true))
 		return NULL;
 
 	a = malloc(sizeof(*a) + size);
diff --git a/src/utils/trace.c b/src/utils/trace.c
index 8f12da8..7c9a17f 100644
--- a/src/utils/trace.c
+++ b/src/utils/trace.c
@@ -197,7 +197,7 @@
 	if (abfd == NULL)
 		return;
 
-	data.pc = (bfd_hostptr_t) ((u8 *) pc - start_offset);
+	data.pc = (uintptr_t) ((u8 *) pc - start_offset);
 	data.found = FALSE;
 	bfd_map_over_sections(abfd, find_addr_sect, &data);
 
@@ -238,7 +238,7 @@
 	if (abfd == NULL)
 		return NULL;
 
-	data.pc = (bfd_hostptr_t) ((u8 *) pc - start_offset);
+	data.pc = (uintptr_t) ((u8 *) pc - start_offset);
 	data.found = FALSE;
 	bfd_map_over_sections(abfd, find_addr_sect, &data);
 
@@ -310,7 +310,7 @@
 	for (i = 0; i < btrace_num; i++) {
 		struct bfd_data data;
 
-		data.pc = (bfd_hostptr_t) ((u8 *) btrace_res[i] - start_offset);
+		data.pc = (uintptr_t) ((u8 *) btrace_res[i] - start_offset);
 		data.found = FALSE;
 		bfd_map_over_sections(abfd, find_addr_sect, &data);