From 905166d1cca7dd256901113b3629e1d149ae8d79 Mon Sep 17 00:00:00 2001 From: Damien Date: Fri, 31 Jul 2026 18:46:33 +0200 Subject: [PATCH] fix(lib): preserve file mode/ownership across ini_set's atomic write MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mktemp defaults to 0600 root:root. The tmpfile+mv swap in ini_set was carrying that over onto the replaced config, silently locking out whatever service account owned the original file (e.g. gitea:www-data on Gitea's app.ini — the service failed to start with a permission denied on its own config after the very first ini_set call). Restore the original file's mode and ownership on the tmpfile before the mv. Verified on both BusyBox (Alpine) and GNU coreutils (Debian) stat -c. Refs #18 --- lib/common.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/common.sh b/lib/common.sh index 605fea5..39765c3 100644 --- a/lib/common.sh +++ b/lib/common.sh @@ -151,6 +151,14 @@ ini_set() { tmp=$(mktemp "${file}.tmp.XXXXXX") + # mktemp defaults to 0600 root:root, which would silently lock the + # service account that owns $file (e.g. gitea:www-data on Gitea's + # app.ini) out of the config this function just wrote. Carry the + # original file's mode/ownership onto the replacement before it lands. + # `stat -c` works identically on GNU coreutils and BusyBox. + chmod "$(stat -c '%a' "$file")" "$tmp" 2>/dev/null || true + chown "$(stat -c '%u:%g' "$file")" "$tmp" 2>/dev/null || true + awk -v section="$section" -v key="$key" -v value="$value" ' /^\[.*\]$/ { if (in_section && !done) {