From 918c839e097857c11fcb6900c32138ea8800a61b Mon Sep 17 00:00:00 2001 From: "Valentin V. Bartenev" Date: Fri, 8 May 2026 02:28:19 +0300 Subject: [PATCH] Web: fix crash/deadlock when disabling web panel via HTTP command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Calling `set web off` through the web panel caused the device to either hang permanently or crash with a Guru Meditation Error (LoadProhibited). Root cause: the HTTP command handler runs inside the httpd task and synchronously called `setWebEnabled(false)`, which called `_panel.stop()` -> `httpd_ssl_stop()` on the very connection that was serving the request. This is unsafe in two ways: 1. `httpd_ssl_stop()` blocks waiting for the httpd task to finish, but the httpd task is the one executing the handler — a self-deadlock. 2. Even if the stop proceeds, closing the active TLS connection from within its own handler triggers lwIP teardown (esp_netif_down_api -> dhcp_stop -> TCP RST) while the WiFi driver is in an inconsistent state, causing a null-pointer dereference in ieee80211_output_do. The deadlock was further compounded by a second concurrent call: while the httpd task was stuck in httpd_ssl_stop(), the main loop kept running, called ensureWebServer(), saw _server != nullptr (never cleared because httpd_ssl_stop() never returned), and issued a second httpd_ssl_stop() on the same handle — blocking the main loop as well and stopping all radio packet processing until reboot. The explicit start/stop calls in setWebEnabled() were redundant: WebService::loop() already calls ensureWebServer() on every iteration, which starts the server when enabled and WiFi is up, and stops it otherwise. Remove the block entirely and let loop() handle both transitions safely from the main loop context, outside the httpd task. --- src/helpers/web/WebService.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/helpers/web/WebService.cpp b/src/helpers/web/WebService.cpp index 85262a44..7a664a30 100644 --- a/src/helpers/web/WebService.cpp +++ b/src/helpers/web/WebService.cpp @@ -56,15 +56,7 @@ bool WebService::setWebEnabled(bool enabled) { if (!enabled) { _suspended_for_ota = false; } - bool ok = savePrefs(); -#if defined(ESP_PLATFORM) && WITH_WEB_PANEL - if (_prefs.web_enabled != 0 && !_suspended_for_ota) { - ensureWebServer(); - } else { - _panel.stop(); - } -#endif - return ok; + return savePrefs(); } bool WebService::setWebStatsEnabled(bool enabled) {