Files
knutwurst--patchdl/src
Knutwurst fcb0a5c3b0 Concurrency: atomic g_stage/g_err, snapshot pkg_diag, safe open, SQLite mutex
g_stage and g_err are now _Atomic. The backend init thread publishes
stage transitions and function-pointer assignments; HTTP request
handlers read g_stage to decide whether to call the Sony API. With the
old `volatile int` reads, nothing in the C memory model ordered the
function-pointer loads against the stage check — a stage==5 sighting
could (in theory) come before the pointer stores were visible. Default
seq_cst on _Atomic gives us the acquire/release pairing for free.

/api/pkgdiag returned g_pkg_diag_json directly with RESPMEM_PERSISTENT,
so MHD's writer thread could read the buffer while record_pkg_diag was
mid-snprintf — torn JSON or a missing NUL terminator. Snapshot under
g_mutex into a heap copy and queue with RESPMEM_MUST_FREE instead.

patchdl_net.c gets fopen_safe(): open() with O_NOFOLLOW|O_CLOEXEC and
mode 0600, then fdopen. The old fopen("wb") follows symlinks (a
malicious symlink at dest_path could redirect the write) and creates
mode 0666 (libc default). Both download paths now use it.

patchdl_appdb opens SQLite with SQLITE_OPEN_FULLMUTEX. Today the scan
runs on the startup thread only, but a future rescan triggered from the
HTTP thread would otherwise race the handle.
2026-06-24 20:35:31 +02:00
..