From 1c3a67b5e815617abf419721525c182d302931aa Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 13 Aug 2026 13:30:53 -0500 Subject: [PATCH] [wifi] Fix ESP8266 crash in cnx_node_search when lwIP transmits after disconnect (#18333) --- .../wifi/wifi_component_esp8266.cpp | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/esphome/components/wifi/wifi_component_esp8266.cpp b/esphome/components/wifi/wifi_component_esp8266.cpp index 719a276bf9..acaa94b13c 100644 --- a/esphome/components/wifi/wifi_component_esp8266.cpp +++ b/esphome/components/wifi/wifi_component_esp8266.cpp @@ -136,10 +136,21 @@ bool WiFiComponent::wifi_apply_power_save_() { https://github.com/d-a-v/Arduino/blob/0e7d21e17144cfc5f53c016191daca8723e89ee8/libraries/ESP8266WiFi/src/ESP8266WiFiSTA.cpp#L251 */ #undef netif_set_addr // need to call lwIP-v1.4 netif_set_addr() +#undef netif_set_down // need to call lwIP-v1.4 netif_set_down() extern "C" { struct netif *eagle_lwip_getif(int netif_index); void netif_set_addr(struct netif *netif, const ip4_addr_t *ip, const ip4_addr_t *netmask, const ip4_addr_t *gw); +void netif_set_down(struct netif *netif); }; + +// The SDK can free its WiFi connection node before taking the STA netif down, letting lwIP +// timers (e.g. IGMP reports armed by mDNS) transmit into the dead driver and crash in +// cnx_node_search; taking the netif down first makes the glue drop such frames (#18308). +static void sta_netif_down() { + struct netif *iface = eagle_lwip_getif(STATION_IF); + if (iface != nullptr) + netif_set_down(iface); +} #endif bool WiFiComponent::wifi_sta_ip_config_(const optional &manual_ip) { @@ -523,6 +534,9 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) { global_wifi_component->sta_state_ = static_cast(ESP8266WiFiSTAState::ERROR_FAILED); } global_wifi_component->error_from_callback_ = true; +#if LWIP_VERSION_MAJOR != 1 + sta_netif_down(); +#endif #ifdef USE_WIFI_CONNECT_STATE_LISTENERS global_wifi_component->pending_.disconnect = true; #endif @@ -536,6 +550,9 @@ void WiFiComponent::wifi_event_callback(System_Event_t *event) { // https://lbsfilm.at/blog/wpa2-authenticationmode-downgrade-in-espressif-microprocessors if (it.old_mode != AUTH_OPEN && it.new_mode == AUTH_OPEN) { ESP_LOGW(TAG, "Potential Authmode downgrade detected, disconnecting"); +#if LWIP_VERSION_MAJOR != 1 + sta_netif_down(); +#endif wifi_station_disconnect(); global_wifi_component->error_from_callback_ = true; } @@ -719,8 +736,12 @@ bool WiFiComponent::wifi_scan_start_(bool passive) { bool WiFiComponent::wifi_disconnect_() { bool ret = true; // Only call disconnect if interface is up - if (wifi_get_opmode() & WIFI_STA) + if (wifi_get_opmode() & WIFI_STA) { +#if LWIP_VERSION_MAJOR != 1 + sta_netif_down(); +#endif ret = wifi_station_disconnect(); + } station_config conf{}; memset(&conf, 0, sizeof(conf)); ETS_UART_INTR_DISABLE();