Files
FTL/patch/civetweb/0001-Add-mbedTLS-debug-logging-hook.patch
T
Dominik 6fc8deed01 Fix thread-safety issues causing SIGSEGV under concurrent API load
pi_hole_extra_headers is a global char[1024] buffer written by API
handlers and read/cleared by civetweb's send_additional_header(), but
civetweb runs up to 50 worker threads concurrently. When multiple
threads handle authenticated requests in parallel, one thread can
overwrite or clear another's header data, causing wrong Set-Cookie
headers to be sent to wrong clients or cookies to be dropped entirely.

Make pi_hole_extra_headers _Thread_local so each worker thread gets its
own buffer. This is safe because civetweb handles each request entirely
within a single thread.

The auth_data session array has a similar race: concurrent threads
read/modify sessions without synchronization. Add a pthread mutex
protecting all auth_data access, using AUTOLOCK/AUTOUNLOCK macros based
on __attribute__((cleanup)) for RAII-style auto-unlock — ensuring the
mutex is released on every exit path, including hidden returns inside
JSON macros that do `return 500` on allocation failure.

Change api->session from a pointer into auth_data to an embedded struct
copy so downstream API handlers read from a per-request snapshot rather
than shared state. Use JSON_COPY_STR_TO_OBJECT for auth_data strings
so the JSON tree owns its own copies after the lock is released.

Fixes: #2824

Signed-off-by: Dominik <dl6er@dl6er.de>
2026-04-05 20:02:16 +02:00

31 lines
1.3 KiB
Diff

diff --git a/src/webserver/civetweb/civetweb.h b/src/webserver/civetweb/civetweb.h
index 2ad76693..52724199 100644
--- a/src/webserver/civetweb/civetweb.h
+++ b/src/webserver/civetweb/civetweb.h
@@ -938,6 +938,10 @@ int my_send_http_error_headers(struct mg_connection *conn,
void FTL_rewrite_pattern(char *filename, size_t filename_buf_len);
+#define MG_CONFIG_MBEDTLS_DEBUG 3
+void FTL_mbed_debug(void *user_param, int level, const char *file,
+ int line, const char *message);
+
// Buffer used for additional "Set-Cookie" headers
#define PIHOLE_HEADERS_MAXLEN 1024
extern _Thread_local char pi_hole_extra_headers[PIHOLE_HEADERS_MAXLEN];
diff --git a/src/webserver/civetweb/mod_mbedtls.inl b/src/webserver/civetweb/mod_mbedtls.inl
index e72685f4..00b9280a 100644
--- a/src/webserver/civetweb/mod_mbedtls.inl
+++ b/src/webserver/civetweb/mod_mbedtls.inl
@@ -83,6 +83,10 @@ mbed_sslctx_init(SSL_CTX *ctx, const char *crt)
mbedtls_ssl_conf_dbg(conf, mbed_debug, (void *)ctx);
#endif
+ /****************** Pi-hole change ******************/
+ mbedtls_ssl_conf_dbg(conf, FTL_mbed_debug, NULL);
+ /****************************************************/
+
/* Initialize TLS key and cert */
mbedtls_pk_init(&ctx->pkey);
mbedtls_ctr_drbg_init(&ctx->ctr);