diff --git a/package/finit/0001-Set-USER-and-LOGNAME-environment-variables-when-drop.patch b/package/finit/0001-Set-USER-and-LOGNAME-environment-variables-when-drop.patch new file mode 100644 index 00000000..8cc5b67a --- /dev/null +++ b/package/finit/0001-Set-USER-and-LOGNAME-environment-variables-when-drop.patch @@ -0,0 +1,48 @@ +From abaad560f0bf1f7de832a55222e20e2a9a61986f Mon Sep 17 00:00:00 2001 +From: Aaron Andersen +Date: Sat, 10 Jan 2026 18:57:52 -0500 +Subject: [PATCH 1/2] Set USER and LOGNAME environment variables when dropping + privileges +Organization: Wires + +When a service is configured to run as a non-root user (@user), finit +correctly drops privileges via setuid() and sets HOME and PATH, but +does not set the USER and LOGNAME environment variables. They remain +set to "root" from boot time. + +This causes problems for software that determines its identity from +the environment rather than getuid(). For example, rootless Podman +checks os.Getenv("USER") first when looking up subordinate UID/GID +ranges in /etc/subuid and /etc/subgid. + +With USER=root but UID=1000, Podman looks up root's subuid entry +instead of the actual user's, causing applications like newuidmap +to fail. Setting USER and LOGNAME to match the actual user identity +follows POSIX conventions and matches the behavior of su, sudo, and +login. + +Signed-off-by: Joachim Wiberg +--- + src/service.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/src/service.c b/src/service.c +index 2c8fb6e..d45db40 100644 +--- a/src/service.c ++++ b/src/service.c +@@ -627,8 +627,11 @@ static pid_t service_fork(svc_t *svc) + set_uid(uid, svc); + + /* Set default path for regular users */ +- if (uid > 0) ++ if (uid > 0) { + setenv("PATH", _PATH_DEFPATH, 1); ++ setenv("USER", svc->username, 1); ++ setenv("LOGNAME", svc->username, 1); ++ } + if (home) { + setenv("HOME", home, 1); + if (chdir(home)) { +-- +2.43.0 + diff --git a/package/finit/0002-Fix-467-TTY-services-stuck-in-restart-state-after-no.patch b/package/finit/0002-Fix-467-TTY-services-stuck-in-restart-state-after-no.patch new file mode 100644 index 00000000..88c8e936 --- /dev/null +++ b/package/finit/0002-Fix-467-TTY-services-stuck-in-restart-state-after-no.patch @@ -0,0 +1,86 @@ +From 34bf9a77765db4d963fc66dde29b415ecc8ab611 Mon Sep 17 00:00:00 2001 +From: Joachim Wiberg +Date: Mon, 12 Jan 2026 19:31:39 +0100 +Subject: [PATCH 2/2] Fix #467: TTY services stuck in restart state after + non-zero exit +Organization: Wires + +When a TTY exited with non-zero code (e.g., user with shell=/sbin/false), +it would enter restart state but never recover, requiring manual restart. + +The throttling logic from commit f0032ab had two issues: + + 1. Duplicate exit code check in service_retry() created infinite timer loop + 2. TTYs lacked default restart_tmo, causing timer to never start + +Fix by removing duplicate check and ensuring TTYs get a 2-second default +restart_tmo for proper throttling. + +Signed-off-by: Joachim Wiberg +--- + src/service.c | 31 ++++++++++++++----------------- + 1 file changed, 14 insertions(+), 17 deletions(-) + +diff --git a/src/service.c b/src/service.c +index d45db40..ff8e180 100644 +--- a/src/service.c ++++ b/src/service.c +@@ -2194,15 +2194,20 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file) + /* only set forking based on pidfile if user supplied pid: option */ + if (pid && svc->pidfile[0] == '!') + svc->forking = 1; ++ } + +- if (svc->restart_tmo == 0) { +- if (svc_is_forking(svc)) +- svc->restart_tmo = 2000; +- else +- svc->restart_tmo = 1; +- } ++ /* Set default restart_tmo for services and TTYs that can restart */ ++ if (svc_is_daemon(svc) && svc->restart_tmo == 0) { ++ if (svc_is_forking(svc)) ++ svc->restart_tmo = 2000; ++ else ++ svc->restart_tmo = 1; + } + ++ /* TTYs need a longer default to throttle errors (e.g., missing device) */ ++ if (svc_is_tty(svc) && svc->restart_tmo == 0) ++ svc->restart_tmo = 2000; ++ + /* Set configured limits */ + memcpy(svc->rlimit, rlimit, sizeof(svc->rlimit)); + +@@ -2631,7 +2636,6 @@ static void service_cleanup_script(svc_t *svc) + static void service_retry(svc_t *svc) + { + char *restart_cnt = (char *)&svc->restart_cnt; +- int rc = WEXITSTATUS(svc->status); + int timeout; + + service_timeout_cancel(svc); +@@ -2641,17 +2645,10 @@ static void service_retry(svc_t *svc) + + if (svc->respawn) { + /* +- * Non-zero exit indicates an error that may not be resolved +- * by immediate retry. Add delay to prevent busy-loop and to +- * rate-limit retries, e.g. when TTY device doesn't exist. ++ * Respawn services (TTYs) that exited with non-zero status ++ * have already been delayed in the SVC_RUNNING_STATE handler. ++ * Just restart now. + */ +- if (WIFEXITED(svc->status) && rc != 0) { +- dbg("%s exited with error %d, delaying respawn ...", +- svc_ident(svc, NULL, 0), rc); +- service_timeout_after(svc, svc->restart_tmo, service_retry); +- return; +- } +- + dbg("%s crashed/exited, respawning ...", svc_ident(svc, NULL, 0)); + svc_unblock(svc); + service_step(svc); +-- +2.43.0 +