Cumulative patch from commit 3e7f1c7980c6e9fc7173f78aa72b2761fcd8924d (DO NOT MERGE)
3e7f1c7 GnuTLS: Add TLS event callbacks for chain success/failure and peer cert
0eb2ed0 GnuTLS: Add support for OCSP stapling as a client
cf08e9b Add MESH to modes capabilities
db5adfe Add SAE to auth_alg capabilities
0e1bb94 GnuTLS: Verify that server certificate EKU is valid for a server
d4d1f5c GnuTLS: Fix tls_disable_time_checks=1 processing
594d1fc GnuTLS: Add support for private_key and client_cert as blobs
79b1dd9 GnuTLS: Fix DER encoding certificate parsing
a165145 Add "GET tls_library" to provide information on TLS library and version
c3bb84b GnuTLS: Add event callbacks
8ddcd6b GnuTLS: Add support for domain_suffix_match
4bc13bf GnuTLS: Check for any unknown verification failure
e0d431a GnuTLS: Add more debug prints for version and session status
65ec7f4 GnuTLS: Move peer certificate validation into callback function
7c82457 GnuTLS: Remove support for versions older than 2.12.x
e1d63f6 GnuTLS: Remove old version number checks for 1.3.2
ae0a23a GnuTLS: Remove GNUTLS_INTERNAL_STRUCTURE_HACK
db4cf40 GnuTLS: Add support for ca_cert as a blob
224104d TLS: Reject openssl_ciphers parameter in non-OpenSSL cases
b09baf3 Work around Windows build issues
6dbbef9 Define host_to_le32() for Windows builds
7d28e46 Fix os_win32 build
0b40247 Remove Network Security Service (NSS) support
d166947 schannel: Reject subject_match, altsubject_match, suffix_match
59051f8 TLS: Reject subject_match, altsubject_match, suffix_match
f8717ac GnuTLS: Reject subject_match, altsubject_match, suffix_match
e24aef1 Fix a typo in domain_suffix_match documentation
394b547 Improve subject_match and domain_suffix_match documentation
8a42a07 trace: Fix out-of-memory testing logic
79cd993 Add address masks to BSSID lists
b83e455 Add network specific BSSID black and white lists
b3d6a0a Add generic parser for MAC address lists
21c74e8 nl80211: Use a helper function to put mesh_id
85e1fad nl80211: Use a helper function for putting beacon interval
6dfc557 Remove mesh_ht_mode network block parameter
54fe48b mesh: Use the shared function with IBSS to determine channel parameters
f7e889f mesh: Convert channel configuration to use common routines
6334330 mesh: Use a separate variable to track whether HT is enabled
1fc4ab2 nl80211: Move debug prints into nl80211_put_freq_params()
cae87ab nl80211: Add a helper function for putting basic rates
6b8b077 ibss/mesh: Enable HT40 if supported
a828f62 Make check_40mhz_2g4 common
fdd989d Make check_20mhz_bss common
0e550fe Make check_40mhz_5g common
6d5d098 Make get_pri_sec_chan() common
5144274 Introduce common allowed_ht40_channel_pair()
5f10b7f Use common hw_get_freq/hw_get_chan helpers in hostapd
269dfe2 Introduce common hw features
1830817 IBSS: Add WPA_DRIVER_FLAGS_HT_IBSS
f3b8ad4 SAE: Implement retransmission timer
a206e2a SAE: Centralize function for sending initial COMMIT
28c91ee bsd: Fix parsing of ieee80211req_scan_result on FreeBSD and DragonFly
96d1d97 Android: Remove hardcoded ICU include paths from hs20-osu-client
a354bcc D-Bus: Use NoMemory error message from CreateInterface
635874b Handle interface disabled/enabled more consistently
8f2cf37 P2P: Indicate reason=UNAVAILABLE for group netdev going down
86a7fbb Verify that eloop_register_read_sock() succeeds for ctrl_iface setup
27d9701 Fix a memory leak on WPA authenticator error path
c1c07dc Fix hostapd interface addition error path
a156ffd Add support for testing memory allocation failures
52b3943 D-Bus: Fix interface unregistration on error path
96dc9a6 D-Bus (old): Fix interface unregistration on error path
ef03557 Fix memory leak on wpa_supplicant_init_wpa() error path
52a8058 TDLS: Fix an interface addition error path
f2d5728 D-Bus: Fix string array dict entry parser in out-of-memory case
c61bc23 D-Bus: Fix byte array dict entry parser in out-of-memory case
dacf605 D-Bus: Fix Introspect() in case of os_strdup() failure
68a8669 D-Bus (old): Fix wpsReg error message
f0614bc D-Bus (old): Fix message handler error paths
a2af1c7 D-Bus (old): Fix memory leak on error path
3d2e2d5 trace: Fix compiler warning on 32-bit builds with bfd support
b9f6560 eloop: Fix WPA_TRACE tracking in case of realloc failure
e10422c Fix memory leak on hostapd BSS addition error path
2801659 Fix hostapd initialization error path on allocation failure
d58ade2 nl80211: Fix compilation with libnl 1.1 and 2.0
51f3427 crypto: Clear temporary stack buffers after use
77a2c39 crypto: Clear temporary heap allocations before freeing
a15a7fc DH: Clear memory explicitly on private key deinit
77c45e2 Add wpabuf_clear_free() to allow clearing of freed memory
a90c7d9 OpenSSL: Fix pbkdf2_sha1() wrapper
f6ebbcf AES-SIV: Make aes_s2v() static
dcf8fbc nl80211: Simplify event processing error paths
38751d8 nl80211: Remove cfg80211 state mismatch workaround for authentication
64ae244 nl80211: Check support for rekey offload on first use
Change-Id: Ice94c3cf8e39a6d2cac993aacd0f6d45b31c7c15
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/utils/common.c b/src/utils/common.c
index 182c6a8..93f1722 100644
--- a/src/utils/common.c
+++ b/src/utils/common.c
@@ -36,6 +36,25 @@
}
+static const char * hwaddr_parse(const char *txt, u8 *addr)
+{
+ size_t i;
+
+ for (i = 0; i < ETH_ALEN; i++) {
+ int a;
+
+ a = hex2byte(txt);
+ if (a < 0)
+ return NULL;
+ txt += 2;
+ addr[i] = a;
+ if (i < ETH_ALEN - 1 && *txt++ != ':')
+ return NULL;
+ }
+ return txt;
+}
+
+
/**
* hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format)
* @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
@@ -44,25 +63,46 @@
*/
int hwaddr_aton(const char *txt, u8 *addr)
{
- int i;
+ return hwaddr_parse(txt, addr) ? 0 : -1;
+}
- for (i = 0; i < 6; i++) {
- int a, b;
- a = hex2num(*txt++);
- if (a < 0)
+/**
+ * hwaddr_masked_aton - Convert ASCII string with optional mask to MAC address (colon-delimited format)
+ * @txt: MAC address with optional mask as a string (e.g., "00:11:22:33:44:55/ff:ff:ff:ff:00:00")
+ * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
+ * @mask: Buffer for the MAC address mask (ETH_ALEN = 6 bytes)
+ * @maskable: Flag to indicate whether a mask is allowed
+ * Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
+ */
+int hwaddr_masked_aton(const char *txt, u8 *addr, u8 *mask, u8 maskable)
+{
+ const char *r;
+
+ /* parse address part */
+ r = hwaddr_parse(txt, addr);
+ if (!r)
+ return -1;
+
+ /* check for optional mask */
+ if (*r == '\0' || isspace(*r)) {
+ /* no mask specified, assume default */
+ os_memset(mask, 0xff, ETH_ALEN);
+ } else if (maskable && *r == '/') {
+ /* mask specified and allowed */
+ r = hwaddr_parse(r + 1, mask);
+ /* parser error? */
+ if (!r)
return -1;
- b = hex2num(*txt++);
- if (b < 0)
- return -1;
- *addr++ = (a << 4) | b;
- if (i < 5 && *txt++ != ':')
- return -1;
+ } else {
+ /* mask specified but not allowed or trailing garbage */
+ return -1;
}
return 0;
}
+
/**
* hwaddr_compact_aton - Convert ASCII string to MAC address (no colon delimitors format)
* @txt: MAC address as a string (e.g., "001122334455")
@@ -144,6 +184,30 @@
}
+int hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask)
+{
+ size_t i;
+ int print_mask = 0;
+ int res;
+
+ for (i = 0; i < ETH_ALEN; i++) {
+ if (mask[i] != 0xff) {
+ print_mask = 1;
+ break;
+ }
+ }
+
+ if (print_mask)
+ res = os_snprintf(buf, len, MACSTR "/" MACSTR,
+ MAC2STR(addr), MAC2STR(mask));
+ else
+ res = os_snprintf(buf, len, MACSTR, MAC2STR(addr));
+ if (os_snprintf_error(len, res))
+ return -1;
+ return res;
+}
+
+
/**
* inc_byte_array - Increment arbitrary length byte array by one
* @counter: Pointer to byte array
diff --git a/src/utils/common.h b/src/utils/common.h
index 7eca409..82a51e5 100644
--- a/src/utils/common.h
+++ b/src/utils/common.h
@@ -164,6 +164,7 @@
#define be_to_host16(n) wpa_swap_16(n)
#define host_to_be16(n) wpa_swap_16(n)
#define le_to_host32(n) (n)
+#define host_to_le32(n) (n)
#define be_to_host32(n) wpa_swap_32(n)
#define host_to_be32(n) wpa_swap_32(n)
@@ -471,6 +472,7 @@
#endif /* __must_check */
int hwaddr_aton(const char *txt, u8 *addr);
+int hwaddr_masked_aton(const char *txt, u8 *addr, u8 *mask, u8 maskable);
int hwaddr_compact_aton(const char *txt, u8 *addr);
int hwaddr_aton2(const char *txt, u8 *addr);
int hex2byte(const char *hex);
@@ -482,6 +484,8 @@
int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
size_t len);
+int hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask);
+
#ifdef CONFIG_NATIVE_WINDOWS
void wpa_unicode2ascii_inplace(TCHAR *str);
TCHAR * wpa_strdup_tchar(const char *str);
diff --git a/src/utils/eloop.c b/src/utils/eloop.c
index 0da6de4..4a565eb 100644
--- a/src/utils/eloop.c
+++ b/src/utils/eloop.c
@@ -242,8 +242,10 @@
eloop_trace_sock_remove_ref(table);
tmp = os_realloc_array(table->table, table->count + 1,
sizeof(struct eloop_sock));
- if (tmp == NULL)
+ if (tmp == NULL) {
+ eloop_trace_sock_add_ref(table);
return -1;
+ }
tmp[table->count].sock = sock;
tmp[table->count].eloop_data = eloop_data;
diff --git a/src/utils/os_unix.c b/src/utils/os_unix.c
index 523a4d0..86fbd0a 100644
--- a/src/utils/os_unix.c
+++ b/src/utils/os_unix.c
@@ -467,9 +467,105 @@
#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;
+
+static int testing_fail_alloc(void)
+{
+ const char *func[WPA_TRACE_LEN];
+ size_t i, res, len;
+ char *pos, *next;
+ int match;
+
+ if (!wpa_trace_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++;
+ 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++;
+
+ pos = wpa_trace_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_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;
+}
+
+#else
+
+static inline int testing_fail_alloc(void)
+{
+ return 0;
+}
+#endif
+
void * os_malloc(size_t size)
{
struct os_alloc_trace *a;
+
+ if (testing_fail_alloc())
+ return NULL;
+
a = malloc(sizeof(*a) + size);
if (a == NULL)
return NULL;
diff --git a/src/utils/os_win32.c b/src/utils/os_win32.c
index 57ee132..296ea13 100644
--- a/src/utils/os_win32.c
+++ b/src/utils/os_win32.c
@@ -12,6 +12,7 @@
#include <wincrypt.h>
#include "os.h"
+#include "common.h"
void os_sleep(os_time_t sec, os_time_t usec)
{
diff --git a/src/utils/trace.c b/src/utils/trace.c
index 7403c08..8484d27 100644
--- a/src/utils/trace.c
+++ b/src/utils/trace.c
@@ -160,7 +160,7 @@
if (abfd == NULL)
return;
- data.pc = (bfd_vma) pc;
+ data.pc = (bfd_hostptr_t) pc;
data.found = FALSE;
bfd_map_over_sections(abfd, find_addr_sect, &data);
@@ -201,7 +201,7 @@
if (abfd == NULL)
return NULL;
- data.pc = (bfd_vma) pc;
+ data.pc = (bfd_hostptr_t) pc;
data.found = FALSE;
bfd_map_over_sections(abfd, find_addr_sect, &data);
@@ -243,6 +243,53 @@
wpa_trace_bfd_addr(pc);
}
+
+size_t wpa_trace_calling_func(const char *buf[], size_t len)
+{
+ bfd *abfd;
+ void *btrace_res[WPA_TRACE_LEN];
+ int i, btrace_num;
+ size_t pos = 0;
+
+ if (len == 0)
+ return 0;
+ if (len > WPA_TRACE_LEN)
+ len = WPA_TRACE_LEN;
+
+ wpa_trace_bfd_init();
+ abfd = cached_abfd;
+ if (!abfd)
+ return 0;
+
+ btrace_num = backtrace(btrace_res, len);
+ if (btrace_num < 1)
+ return 0;
+
+ for (i = 0; i < btrace_num; i++) {
+ struct bfd_data data;
+
+ data.pc = (bfd_hostptr_t) btrace_res[i];
+ data.found = FALSE;
+ bfd_map_over_sections(abfd, find_addr_sect, &data);
+
+ while (data.found) {
+ if (data.function &&
+ (pos > 0 ||
+ os_strcmp(data.function, __func__) != 0)) {
+ buf[pos++] = data.function;
+ if (pos == len)
+ return pos;
+ }
+
+ data.found = bfd_find_inliner_info(abfd, &data.filename,
+ &data.function,
+ &data.line);
+ }
+ }
+
+ return pos;
+}
+
#else /* WPA_TRACE_BFD */
#define wpa_trace_bfd_init() do { } while (0)
diff --git a/src/utils/trace.h b/src/utils/trace.h
index 38f43fb..43ed86c 100644
--- a/src/utils/trace.h
+++ b/src/utils/trace.h
@@ -40,6 +40,7 @@
dl_list_del(&(ptr)->wpa_trace_ref_##name.list); \
} while (0)
void wpa_trace_check_ref(const void *addr);
+size_t wpa_trace_calling_func(const char *buf[], size_t len);
#else /* WPA_TRACE */
diff --git a/src/utils/wpabuf.c b/src/utils/wpabuf.c
index b257b36..7aafa0a 100644
--- a/src/utils/wpabuf.c
+++ b/src/utils/wpabuf.c
@@ -205,6 +205,15 @@
}
+void wpabuf_clear_free(struct wpabuf *buf)
+{
+ if (buf) {
+ os_memset(wpabuf_mhead(buf), 0, wpabuf_len(buf));
+ wpabuf_free(buf);
+ }
+}
+
+
void * wpabuf_put(struct wpabuf *buf, size_t len)
{
void *tmp = wpabuf_mhead_u8(buf) + wpabuf_len(buf);
diff --git a/src/utils/wpabuf.h b/src/utils/wpabuf.h
index dbce925..c3ef1ba 100644
--- a/src/utils/wpabuf.h
+++ b/src/utils/wpabuf.h
@@ -32,6 +32,7 @@
struct wpabuf * wpabuf_alloc_copy(const void *data, size_t len);
struct wpabuf * wpabuf_dup(const struct wpabuf *src);
void wpabuf_free(struct wpabuf *buf);
+void wpabuf_clear_free(struct wpabuf *buf);
void * wpabuf_put(struct wpabuf *buf, size_t len);
struct wpabuf * wpabuf_concat(struct wpabuf *a, struct wpabuf *b);
struct wpabuf * wpabuf_zeropad(struct wpabuf *buf, size_t len);