From de978414cec7067837d8f0c8eba755c63254a808 Mon Sep 17 00:00:00 2001 From: "Valentin V. Bartenev" Date: Fri, 8 May 2026 01:38:09 +0300 Subject: [PATCH] Fix: remove redundant stopRedirectServer() call from ensureWebServer() When the "start ota" command was issued from the web panel, a race condition could occur between the main loop thread and the HTTP server thread: - HTTP thread: prepareForOTAStart() -> stopRedirectServer() -> httpd_stop(_redirect_server) [blocking] - Main thread: loop() -> ensureWebServer() -> stopRedirectServer() -> httpd_stop(_redirect_server) [double free!] Because stopRedirectServer() sets _redirect_server = nullptr only after httpd_stop() returns, both threads could pass the nullptr check simultaneously, resulting in a double free and heap corruption: CORRUPT HEAP: Bad head at 0x3fcb1f24. Expected 0xabba1234 got 0x3fca5f34 assert failed: multi_heap_free multi_heap_poisoning.c:259 (head != NULL) The call in ensureWebServer() was added as a safety net in commit 4b83142b, but is redundant: prepareForOTAStart() already calls stopRedirectServer() synchronously before startOTAUpdate() occupies port 80. Removing it eliminates the race condition. The bug only manifested when OTA was triggered from the web panel (HTTP thread), not from radio (main thread), because in the latter case both calls happen on the same thread and cannot race. --- src/helpers/web/WebService.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/helpers/web/WebService.cpp b/src/helpers/web/WebService.cpp index 2f588d11..85262a44 100644 --- a/src/helpers/web/WebService.cpp +++ b/src/helpers/web/WebService.cpp @@ -103,9 +103,6 @@ void WebService::ensureWebServer() { return; } if (_suspended_for_ota) { - if (_panel.isRunning()) { - _panel.stopRedirectServer(); - } return; } if (_panel.isRunning()) {