The sources are now copied from https://github.com/DL6ER/civetweb (branch
`pi-hole`), which is CivetWeb master plus the fixes we have pending upstream.
That branch stays deliberately close to master - only necessary and security
fixes go on it, everything Pi-hole specific stays in `patch/civetweb/`.
This picks up two memory-safety fixes we were missing: the integer underflow in
the multipart form field length, where `next` can point before `hend` on a
malformed part and the unchecked pointer subtraction underflows `size_t`, and
the endless loop on a truncated URL-encoded body. Neither is upstream yet, so
waiting for a CivetWeb release would not have given us either. It also brings
the error status for custom error pages, which we need for the static web
interface.
`patch/civetweb.sh` now applies the stack with `git apply --3way` rather than
`patch`. This is not cosmetic: `patch` matches hunks by surrounding context and
silently applies them elsewhere when that context has drifted. Dropping our
sources in and running the old script applied three patches into the wrong place
while still reporting success, so `mg_request_info.csrf_token`, the
`mg_server_port.addr` union and the thread `setpriority()` call all vanished and
the tree no longer compiled. A three-way merge uses the blob a patch was
generated against and either merges correctly or leaves a real conflict, and it
copes with code moving around - which is the normal case after a bump. The
script also fails now instead of printing that everything applied okay.
The Kepler patch had lost the leading space on three of its context lines, which
GNU `patch` tolerates and `git apply` rejects; those are restored.
The PROXY protocol v2 patch is dropped: it is on the fork as a commit, so
carrying it here as well conflicts.
Signed-off-by: DL6ER <dl6er@dl6er.de>
Since the migration from mbedTLS to OpenSSL (#2941), OpenSSL surfaces the
TLS alert a browser sends when it rejects our self-signed certificate
(`certificate_unknown` / `unknown_ca`) on its error queue. CivetWeb dumps
that queue verbatim through `mg_cry_internal`, so `webserver.log` now fills
with `sslize error: ...` lines on every fresh connection - something
mbedTLS silently swallowed before.
Such a handshake is recoverable, i.e., the user clicks through the warning
and the connection proceeds, so it is not really an error on our side. When
the failing `sslize` runs in a server context and the reason is a received
TLS alert (reason >= `SSL_AD_REASON_OFFSET`), log it via `DEBUG_TRACE`
instead, which only prints when `debug.webserver` is enabled. Genuine SSL
errors and the client path keep crying into the log as before.
The in-tree `civetweb.c` change is mirrored in
`patch/civetweb/0001-Demote-server-side-TLS-handshake-alerts-to-debug.patch`
so it survives the next CivetWeb update.
Signed-off-by: DL6ER <dl6er@dl6er.de>
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>