From 29da4e9279e1aa35431c42398133a65f051e7a9b Mon Sep 17 00:00:00 2001 From: Our Air Quality Date: Fri, 18 Aug 2017 17:36:00 +1000 Subject: [PATCH] sdk_cnx_add_rc: fix overflow of the table, when no match is found. Also adds source code for sdk_cnx_rc_search, adding a null pointer dereference check (that is not expected to be seen), and source code for sdk_cnx_remove_rc. --- core/include/sdk_internal.h | 10 ++-- open_esplibs/libnet80211/wl_cnx.c | 79 ++++++++++++++++++++++++++++++- open_esplibs/libwpa/wpa_main.c | 2 +- 3 files changed, 83 insertions(+), 8 deletions(-) diff --git a/core/include/sdk_internal.h b/core/include/sdk_internal.h index 3dfa8df..a4e21c6 100644 --- a/core/include/sdk_internal.h +++ b/core/include/sdk_internal.h @@ -25,14 +25,14 @@ struct sdk_info_st { }; -struct _unknown_info1 { +struct wl_channel { uint8_t _unknown00; uint8_t _unknown01; uint8_t _unknown02; uint8_t _unknown03; uint8_t _unknown04; uint8_t _unknown05; - uint8_t channel; // eagle_auth_done + uint8_t num; // eagle_auth_done }; @@ -98,7 +98,7 @@ struct sdk_cnx_node { uint32_t _unknown1c[23]; - struct _unknown_info1 *_unknown78; // eagle_auth_done + struct wl_channel *channel; // 0x78 eagle_auth_done uint32_t _unknown7c[8]; @@ -322,7 +322,7 @@ struct esf_buf { _Static_assert(sizeof(struct sdk_info_st) == 0x24, "info_st is the wrong size!"); _Static_assert(offsetof(struct sdk_info_st, sta_mac_addr) == 0x1e, "bad struct"); -_Static_assert(offsetof(struct _unknown_info1, channel) == 0x06, "bad struct"); +_Static_assert(offsetof(struct wl_channel, num) == 0x06, "bad struct"); _Static_assert(sizeof(struct _unknown_softap2) == 0xcc, "_unknown_softap2 is the wrong size!"); _Static_assert(offsetof(struct _unknown_softap2, _unknownb8) == 0xb8, "bad struct"); @@ -333,7 +333,7 @@ _Static_assert(offsetof(struct _unknown_softap1, _unknown18) == 0x18, "bad struc _Static_assert(sizeof(struct _unknown_wpa1) == 0x4c, "_unknown_wpa1 is the wrong size!"); _Static_assert(offsetof(struct _unknown_wpa1, _unknown48) == 0x48, "bad struct"); -_Static_assert(offsetof(struct sdk_cnx_node, _unknown78) == 0x78, "bad struct"); +_Static_assert(offsetof(struct sdk_cnx_node, channel) == 0x78, "bad struct"); _Static_assert(offsetof(struct sdk_cnx_node, _unknown108) == 0x108, "bad struct"); _Static_assert(offsetof(struct sdk_g_ic_netif_info, started) == 0xbb, "bad struct"); diff --git a/open_esplibs/libnet80211/wl_cnx.c b/open_esplibs/libnet80211/wl_cnx.c index 0d2459e..3b49c5d 100644 --- a/open_esplibs/libnet80211/wl_cnx.c +++ b/open_esplibs/libnet80211/wl_cnx.c @@ -11,8 +11,10 @@ #include #include "lwip/dhcp.h" -ETSTimer sdk_sta_con_timer; -void *sdk_g_cnx_probe_rc_list_cb; +/* Need to use the sdk versions of these for now as there are reference to them + * relative to other data structres. */ +extern ETSTimer sdk_sta_con_timer; +extern void *sdk_g_cnx_probe_rc_list_cb; /* * Called from the ESP sdk_cnx_sta_leave function. Split out via a hack to the @@ -26,6 +28,79 @@ void dhcp_if_down(struct netif *netif) netif_set_down(netif); } +struct sdk_cnx_node *sdk_cnx_rc_search(uint8_t *hwaddr) { + size_t len = *(uint8_t *)(sdk_g_ic.v._unknown0 + 0x689); + struct sdk_cnx_node **table = (struct sdk_cnx_node **)(sdk_g_ic.v._unknown0 + 0x670); + size_t i; + + for (i = 0; i < len; i++) { + struct sdk_cnx_node *cnx_node = table[i]; + if (cnx_node && memcmp(cnx_node->mac_addr, hwaddr, 6) == 0) { + return cnx_node; + } + } + + return NULL; +} + +int sdk_cnx_add_rc(struct sdk_cnx_node *cnx_node) { + size_t len = *(uint8_t *)(sdk_g_ic.v._unknown0 + 0x689); + struct sdk_cnx_node **table = (struct sdk_cnx_node **)(sdk_g_ic.v._unknown0 + 0x670); + + if (len >= 6) { + return -1; + } + + if (len < 2) { + table[len] = cnx_node; + } else { + struct wl_channel *channel = cnx_node->channel; + size_t found; + for (found = 0; found < len; found++) { + if (table[found]->channel == channel) { + break; + } + } + + if (found >= len) { + /* Add to the end. */ + table[len] = cnx_node; + } else { + /* Make room. */ + size_t next = found + 1; + size_t i; + for (i = len; i > next; i--) { + table[i] = table[i - 1];; + } + table[next] = cnx_node; + } + } + + *(uint8_t *)(sdk_g_ic.v._unknown0 + 0x689) += 1; + return 0; +} + +void sdk_cnx_remove_rc(struct sdk_cnx_node *cnx_node) { + size_t len = *(uint8_t *)(sdk_g_ic.v._unknown0 + 0x689); + struct sdk_cnx_node **table = (struct sdk_cnx_node **)(sdk_g_ic.v._unknown0 + 0x670); + size_t i; + + for (i = 0; i < len; i++) { + if (table[i] == cnx_node) { + bzero(cnx_node, 0x110); + table[i] = NULL; + len -= 1; + *(uint8_t *)(sdk_g_ic.v._unknown0 + 0x689) = len; + break; + } + } + + /* Fill the hole */ + for (; i < len; i++) { + table[i] = table[i + 1]; + } +} + #if 0 // Most of the code in this file assesses static data so it will be all or none. diff --git a/open_esplibs/libwpa/wpa_main.c b/open_esplibs/libwpa/wpa_main.c index 43f332c..e13e3b6 100644 --- a/open_esplibs/libwpa/wpa_main.c +++ b/open_esplibs/libwpa/wpa_main.c @@ -77,7 +77,7 @@ void sdk_eagle_auth_done() { if (cnx_node->_unknown08 & 1) return; - uint32_t channel = cnx_node->_unknown78->channel; + uint32_t channel = cnx_node->channel->num; char *ssid = (char *)sdk_g_ic.s.sta_ssid.ssid; printf("\nconnected with %s, channel %d\n", ssid, channel);