fix: harden quota probe subprocess handling - #2030
1 commit merged into
Conversation
SummaryRead the diff at The preexec_fn path is unsafe in the multithreaded WebUIThe WebUI HTTP server is
The PR wires if hasattr(os, "fork"): # POSIX
kwargs["preexec_fn"] = _account_usage_preexec_fn…where the preexec body itself does: def _account_usage_preexec_fn() -> None:
try:
import ctypes
libc = ctypes.CDLL(None)
libc.prctl(1, signal.SIGTERM) # PR_SET_PDEATHSIG=1, SIGTERM=15
except Exception:
passIn practice the The bootstrap path already covers the same invariant — safelyThe PR also installs There is one tiny window the preexec covered that the bootstrap doesn't: RecommendationDrop the kwargs: dict[str, Any] = {
"stdin": subprocess.DEVNULL,
"stdout": subprocess.PIPE,
"stderr": subprocess.PIPE,
"text": True,
"timeout": _ACCOUNT_USAGE_SUBPROCESS_TIMEOUT_SECONDS,
"check": False,
}
# Parent-death signal is installed by _ACCOUNT_USAGE_PARENT_DEATHSIG_BOOTSTRAP
# inside the child interpreter (after exec) — safer than preexec_fn in a
# multithreaded server (CPython docs warn about fork-without-exec hazards).That removes the Test-only nit (non-blocking)
Otherwise
LGTM modulo the preexec_fn removal. |
50acda3
Thinking Path
What Changed
stdin=subprocess.DEVNULLfor the quota child process.preexec_fnand child bootstrap wiring forprctl(PR_SET_PDEATHSIG, SIGTERM)so probe children receive SIGTERM when the WebUI parent dies.Why It Matters
Verification
python3 -m py_compile api/providers.pygit diff --checkenv -u HERMES_CONFIG_PATH -u HERMES_WEBUI_HOST /home/michael/.hermes/hermes-agent/venv/bin/python -m pytest tests/test_provider_quota_status.py -q→17 passed in 6.52senv -u HERMES_CONFIG_PATH -u HERMES_WEBUI_HOST /home/michael/.hermes/hermes-agent/venv/bin/python -m pytest tests/ -k provider -x -q→486 passed, 4614 deselected, 1 warning in 185.04sRisks / Follow-ups
preexec_fnis only wired on POSIX. Non-POSIX platforms keep the prior subprocess behavior plus DEVNULL/concurrency cap.Refs #1912
Model Used
minimax/minimax-m2.7for implementation and first-pass test execution.