fix(cron): do not treat directories as unsafe lifecycle scripts (#86753)

Docker Desktop writes fpath=(~/.docker/completions ...) into .zshrc.
The referenced-script walk then opened that directory, saw a non-regular
file, and fail-closed — blocking source ~/.zshrc on every terminal
command. Directories are not scripts; devices stay fail-closed.
This commit is contained in:
Jasmine Naderi
2026-08-15 05:00:34 -04:00
committed by Teknium
parent 08baf96537
commit 9ac1e65b0a
2 changed files with 58 additions and 7 deletions

View File

@@ -440,6 +440,13 @@ def _read_referenced_script(path: Path) -> tuple[Optional[str], bool]:
try:
metadata = os.fstat(descriptor)
if not stat.S_ISREG(metadata.st_mode):
# Directories are not scripts. Docker Desktop writes
# ``fpath=(~/.docker/completions …)`` into ``~/.zshrc``; the
# walk then treats that dir as a referenced script and used
# to fail-closed, blocking ``source ~/.zshrc`` (#86753).
# Devices/sockets stay fail-closed.
if stat.S_ISDIR(metadata.st_mode):
return None, False
return None, True
# Sniff a small prefix first: files that are clearly compiled
# binaries (executable magic, or NUL bytes in the head) are never

View File

@@ -1204,11 +1204,55 @@ class TestLifecycleGuardNeverRaises:
weird.write_bytes(b"\xff\xfe\x00\x01 not really a script")
assert self._scan(f"bash {weird}") is False
def test_sourced_zshrc_docker_completions_dir_is_not_blocked(self, tmp_path):
"""#86753: Docker Desktop writes ``fpath=(~/.docker/completions …)``
into ``.zshrc``. Completions is a directory. The walk must treat
that as nothing-to-scan, not fail-closed, or ``source ~/.zshrc``
is blocked on every terminal command."""
completions = tmp_path / ".docker" / "completions"
completions.mkdir(parents=True)
zshrc = tmp_path / ".zshrc"
zshrc.write_text(
f"fpath=({completions} /usr/local/share/zsh/site-functions $fpath)\n",
encoding="utf-8",
)
assert self._scan(f"source {zshrc}") is False
def test_fstat_directory_mode_is_not_unsafe(self, tmp_path, monkeypatch):
"""#86753 Unix contract: os.open(dir) succeeds, fstat is not S_ISREG.
Windows raises OSError on os.open(dir) and already returns
nothing-to-scan. Linux/macOS open the directory and used to
return unsafe=True, blocking sourced zshrcs that mention
``~/.docker/completions``.
"""
import os
import stat as statmod
from cron.lifecycle_guard import _read_referenced_script
probe = tmp_path / "probe"
probe.write_text("echo hi\n", encoding="utf-8")
orig = os.fstat
def _dir_fstat(fd):
orig(fd)
class _DirStat:
st_mode = statmod.S_IFDIR | 0o755
return _DirStat()
monkeypatch.setattr(os, "fstat", _dir_fstat)
text, unsafe = _read_referenced_script(probe)
assert text is None
assert unsafe is False
def test_directory_and_dev_null_fail_closed_not_crash(self, tmp_path):
# Non-regular files are suspicious (fail closed = blocked), but the
# important contract is: verdict, not exception.
assert self._scan(f"bash {tmp_path}") is True
assert self._scan("bash /dev/null") is True
# Directories are not scripts (#86753). Devices stay fail-closed
# where the OS actually exposes them (POSIX /dev/null).
# The important contract is: verdict, not exception.
assert self._scan(f"bash {tmp_path}") is False
if os.name != "nt":
assert self._scan("bash /dev/null") is True
def test_magic_prefix_binaries_skipped_without_full_read(self, tmp_path):
"""Executable magic (ELF/PE/Mach-O) short-circuits the read: the
@@ -1236,8 +1280,8 @@ class TestLifecycleGuardNeverRaises:
)
binary = tmp_path / "prog"
binary.write_bytes(b"\x7fELF" + bytes(128))
for value in ("nul\x00byte.sh", str(binary), "/nonexistent/x.sh"):
for value in ("nul\x00byte.sh", str(binary), "/nonexistent/x.sh", str(tmp_path)):
check_gateway_lifecycle("clean prompt", value) # must not raise
for value in ("/dev/null", str(tmp_path)):
if os.name != "nt":
with pytest.raises(GatewayLifecycleBlocked):
check_gateway_lifecycle("clean prompt", value)
check_gateway_lifecycle("clean prompt", "/dev/null")