Reject unsupported server arguments

This commit is contained in:
root
2026-07-19 23:15:22 +00:00
parent 881dba078a
commit cd993b34e9
4 changed files with 105 additions and 1 deletions
+12
View File
@@ -280,6 +280,18 @@ scripts/systemd/manage-uce-service.sh restart
scripts/systemd/manage-uce-service.sh logs 200 scripts/systemd/manage-uce-service.sh logs 200
``` ```
The server binary accepts only these process modes:
```bash
bin/uce_fastcgi.linux.bin # start the server
bin/uce_fastcgi.linux.bin --precompile
bin/uce_fastcgi.linux.bin --help
```
Help and invalid arguments exit before configuration is loaded or any listener
is opened. Invalid or extra arguments return status 2. This ordering prevents a
diagnostic invocation from replacing or removing a configured Unix socket.
Managed restart builds and precompiles the complete candidate ABI generation Managed restart builds and precompiles the complete candidate ABI generation
before it switches the service. Precompile uses two low-priority processes by before it switches the service. Precompile uses two low-priority processes by
default; set `PRECOMPILE_JOBS` in `/etc/uce/settings.cfg` to tune the bounded default; set `PRECOMPILE_JOBS` in `/etc/uce/settings.cfg` to tune the bounded
+1
View File
@@ -87,5 +87,6 @@ if [[ "$action" == "run" ]]; then
timeout --signal=TERM --kill-after=5s 120s scripts/test_wasm_metadata_buffer.sh timeout --signal=TERM --kill-after=5s 120s scripts/test_wasm_metadata_buffer.sh
timeout --signal=TERM --kill-after=5s 150s scripts/test_wasm_metadata_deadline.sh timeout --signal=TERM --kill-after=5s 150s scripts/test_wasm_metadata_deadline.sh
scripts/test_wasm_source_locations.sh scripts/test_wasm_source_locations.sh
scripts/test_server_arguments.sh
scripts/test_socket_activation.sh scripts/test_socket_activation.sh
fi fi
+69
View File
@@ -0,0 +1,69 @@
#!/usr/bin/env bash
set -euo pipefail
cd "$(dirname "$0")/.."
binary="$PWD/bin/uce_fastcgi.linux.bin"
root=$(mktemp -d /tmp/uce-server-arguments.XXXXXX)
listener_pid=""
cleanup() {
[[ -n "$listener_pid" ]] && kill "$listener_pid" 2>/dev/null || true
rm -rf "$root"
}
trap cleanup EXIT
cfg="$root/settings.cfg"
socket_path="$root/sentinel.sock"
cp /etc/uce/settings.cfg "$cfg"
sed -E -i \
-e "s|^[[:space:]]*FCGI_SOCKET_PATH[[:space:]]*=.*|FCGI_SOCKET_PATH=|" \
-e "s|^[[:space:]]*FCGI_PORT[[:space:]]*=.*|FCGI_PORT=|" \
-e "s|^[[:space:]]*CLI_SOCKET_PATH[[:space:]]*=.*|CLI_SOCKET_PATH=$socket_path|" \
-e "s|^[[:space:]]*HTTP_PORT[[:space:]]*=.*|HTTP_PORT=|" \
-e "s|^[[:space:]]*PROACTIVE_COMPILE_ENABLED[[:space:]]*=.*|PROACTIVE_COMPILE_ENABLED=false|" \
-e "s|^[[:space:]]*WORKER_COUNT[[:space:]]*=.*|WORKER_COUNT=1|" \
-e "s|^[[:space:]]*BIN_DIRECTORY[[:space:]]*=.*|BIN_DIRECTORY=$root/bin|" \
-e "s|^[[:space:]]*TMP_UPLOAD_PATH[[:space:]]*=.*|TMP_UPLOAD_PATH=$root/upload|" \
-e "s|^[[:space:]]*SESSION_PATH[[:space:]]*=.*|SESSION_PATH=$root/session|" \
"$cfg"
python3 -c 'import socket,sys,time; s=socket.socket(socket.AF_UNIX); s.bind(sys.argv[1]); s.listen(); time.sleep(30)' "$socket_path" &
listener_pid=$!
for _ in $(seq 1 50); do
[[ -S "$socket_path" ]] && break
sleep 0.02
done
[[ -S "$socket_path" ]]
socket_inode=$(stat -c %i "$socket_path")
invoke() {
local output="$1"
shift
timeout --signal=TERM --kill-after=1s 2s unshare --mount --fork \
bash -c 'mount --bind "$1" /etc/uce/settings.cfg; exec "$2" "${@:3}"' \
_ "$cfg" "$binary" "$@" >"$output.stdout" 2>"$output.stderr"
}
for option in --help -h; do
invoke "$root/help" "$option"
grep -q '^Usage: uce_fastcgi' "$root/help.stdout"
grep -q -- '--precompile' "$root/help.stdout"
[[ ! -s "$root/help.stderr" ]]
done
for arguments in '--unknown' '--precompile extra' '--help extra'; do
read -r -a argv <<<"$arguments"
set +e
invoke "$root/invalid" "${argv[@]}"
rc=$?
set -e
[[ $rc -eq 2 ]]
grep -q '^invalid arguments$' "$root/invalid.stderr"
grep -q '^Usage: uce_fastcgi' "$root/invalid.stderr"
[[ ! -s "$root/invalid.stdout" ]]
done
[[ -S "$socket_path" ]]
[[ "$(stat -c %i "$socket_path")" == "$socket_inode" ]]
kill -0 "$listener_pid"
echo 'server argument handling passed: help and invalid arguments exited before listener setup'
+23 -1
View File
@@ -1866,17 +1866,39 @@ int precompile_unit_generation()
return(total.failed == 0 && !candidate_rejected ? 0 : 1); return(total.failed == 0 && !candidate_rejected ? 0 : 1);
} }
void print_fastcgi_usage(FILE* stream)
{
fprintf(stream,
"Usage: uce_fastcgi [--precompile]\n"
" uce_fastcgi --help\n\n"
"Without options, start the FastCGI server.\n"
" --precompile Compile the current source generation without starting listeners.\n"
" -h, --help Show this help and exit.\n");
}
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
// systemd connects stdout to a pipe, which otherwise block-buffers child // systemd connects stdout to a pipe, which otherwise block-buffers child
// diagnostics and assigns stale failures a misleading later journal time. // diagnostics and assigns stale failures a misleading later journal time.
setvbuf(stdout, 0, _IOLBF, 0); setvbuf(stdout, 0, _IOLBF, 0);
setvbuf(stderr, 0, _IONBF, 0); setvbuf(stderr, 0, _IONBF, 0);
if(argc == 2 && (String(argv[1]) == "--help" || String(argv[1]) == "-h"))
{
print_fastcgi_usage(stdout);
return(0);
}
bool precompile = argc == 2 && String(argv[1]) == "--precompile";
if(argc != 1 && !precompile)
{
fprintf(stderr, "invalid arguments\n");
print_fastcgi_usage(stderr);
return(2);
}
// Warm up libgcc's backtrace state so the first in-handler backtrace() // Warm up libgcc's backtrace state so the first in-handler backtrace()
// after a fault does not allocate. // after a fault does not allocate.
backtrace(request_fault_frames, 4); backtrace(request_fault_frames, 4);
process_start_directory(); process_start_directory();
if(argc == 2 && String(argv[1]) == "--precompile") if(precompile)
return(precompile_unit_generation()); return(precompile_unit_generation());
init_base_process(); init_base_process();