fix(security): guard os.chmod(parent) against / and top-level dirs

Five call sites do os.chmod(path.parent, 0o700) without checking that
the parent resolves to a safe directory. If HERMES_HOME or another
path env var resolves to /, the chmod strips traversal permission from
the root inode and bricks the entire host.

Add secure_parent_dir() to hermes_constants.py that refuses to chmod
/ or any top-level directory (depth < 2). Replace all 5 call sites
with this helper.

Fixes #25821
This commit is contained in:
liuhao1024 2026-05-15 00:28:39 +08:00 committed by Teknium
parent 3bbe980115
commit 4ead464f97
5 changed files with 127 additions and 22 deletions

View file

@ -235,6 +235,27 @@ def display_hermes_home() -> str:
return str(home)
def secure_parent_dir(path: Path) -> None:
"""Chmod ``0o700`` on the parent directory of *path*, but only if safe.
Refuses to chmod ``/`` or any top-level directory (depth < 2) to
prevent catastrophic host bricking when ``HERMES_HOME`` or other
path env vars resolve to an unexpected location.
See https://github.com/NousResearch/hermes-agent/issues/25821.
"""
parent = path.parent.resolve()
# Refuse root and its direct children (/usr, /home, /var, /tmp, …).
if parent == Path("/") or len(parent.parts) < 3:
return
try:
os.chmod(parent, 0o700)
except OSError:
pass
def get_subprocess_home() -> str | None:
"""Return a per-profile HOME directory for subprocesses, or None.