Repository navigation
Start scripts that run, log and time out; the message bus socket leaves /tmp - #2
Merged
Merged
Conversation
inkly
commented
Sep 22, 2026
Collaborator
- ExecuteScripts read the shebang after closing the file (every script ran with /bin/sh), threw each script's output away, stopped at the first failure and had no time limit, so a hung script held the core's start until systemd restarted it in a loop. Scripts now run with their shebang (read like the kernel does), through os/exec, for at most 60 seconds (the whole process group is killed on Linux), each run is logged with its output, and a failure does not stop the next ones.
- The message bus socket moves from /tmp, where any local user could squat the path, to the runtime path: MessageBusSocketPath(runtimePath). PublishEventInSocket takes the runtime path (breaking; its only caller is AppManagement).
- InternalAuthorization(runtimePath) gives the internal credential for websocket handshakes.
… logs ExecuteScripts read the shebang after closing the file, so every script ran with /bin/sh, and it passed the whole shebang as the program name, so '#!/usr/bin/env bash' could not have worked either. It threw the output away, stopped at the first failing script and had no time limit, so a hung script held the start of CasaOS until systemd killed it, again at every restart. Now each regular file of the directory runs in name order with the program and optional argument of its shebang line, for at most ScriptTimeout (60 seconds). On Linux the script gets its own process group and a timeout kills the whole group; elsewhere only the script's process is killed and WaitDelay stops waiting for pipes its children keep open. Each run is logged with its name, interpreter, exit code, duration and the last 4 KB of its output, at Info or Error. A failure no longer stops the next scripts; the failures come back joined. A missing directory is logged and is not an error.
PublishEventInSocket posted to /tmp/message-bus.sock. /tmp is world-writable, so any local user could create that path first and keep the message bus from listening, or answer in its place. The socket now lives in the runtime path, which only root can write: MessageBusSocketPath(runtimePath) returns it, and PublishEventInSocket takes the runtime path as its second argument. The message bus must listen on the same path. The dial and the request now follow the caller's context, and keep-alive is off: each call builds its own transport, and the idle connection it kept was never reused nor closed.
A websocket handshake from x/net/websocket takes its headers from Config.Header, where a request editor does not fit. InternalAuthorization(runtimePath) returns "Internal <secret>" when the secret file is readable and an empty string otherwise, so such a caller can set the header itself. InternalRequestEditor and the HTTP helpers now go through it; their behaviour does not change.
…, and warn about kept pipes utils/exec's injection check refused shebang arguments with a space and script names with one, though no shell ever sees them: scripts now go straight to os/exec. The first line is read the way the kernel reads it, at most 256 bytes, so a long first line no longer fails the script. A start.d entry that cannot be stat'ed is logged instead of skipped silently, and a script whose daemon kept its output open is logged as a warning: that daemon dies of SIGPIPE on its next write. A #!/bin/cat case proves the shebang's program is the one that runs.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.