Repository navigation
fix(computer): guard Unix-only pwd import in site_proxy - #519
Conversation
|
Added a fresh-import test (test_the_proxy_imports_when_pwd_is_unavailable) that blocks pwd in sys.modules and reloads site_proxy to verify it imports cleanly without the module. |
andrewpark-scaleai
left a comment
There was a problem hiding this comment.
Requesting changes, mainly because this doesn't achieve its stated goal.
It still doesn't import on non-Unix. I blocked every Unix-only module (pwd, fcntl, grp, termios, resource, pty, tty) and imported agent_env.env.envs.computer.utils.sites and computer.env at this head. Both still fail at src/agent_env/store/object_store/local/store.py:27, which does an unconditional import fcntl. The PR only gets past pwd, so the same import chain still breaks on Windows. bundle/_fs.py:18 also says agent-env doesn't target Windows. Which platform hit this? If there is a real non-Unix caller, fcntl needs a guard too. If there isn't one, I'd close this.
Keep the change to the import itself. serve, drop_privileges, install and trust_nss only run as root inside the Linux computer, on the base's own python3. The only host-side import of this module is sites.py:36, which takes is_local and matches. A try/except around import pwd, or moving those two functions into a module with no pwd dependency, covers the host case. That makes the runtime guards unnecessary. Details are inline.
| os.setgroups([]) | ||
| os.setgid(entry.pw_gid) | ||
| os.setuid(entry.pw_uid) | ||
| if hasattr(os, "setgroups"): |
There was a problem hiding this comment.
These hasattr checks can't be false. This branch is only reachable after os.geteuid() == 0, which only happens on a Unix host where setgroups, setgid and setuid all exist. And if one of them ever were missing, the privilege drop would be silently skipped while the code carried on as root. A privilege drop shouldn't fail that way. Please revert to the unconditional calls.
There was a problem hiding this comment.
Reverted to unconditional calls.
| return [] | ||
| try: | ||
| home = Path(pwd.getpwnam(user).pw_dir) | ||
| except KeyError: |
There was a problem hiding this comment.
This changes behavior on Linux, and the description doesn't mention it. Before, an unknown session user raised KeyError and install failed loudly. Now it returns [], so a misnamed user silently skips NSS trust, and the first symptom is a certificate error in Chromium much later. The pwd is None check above is enough for the import case. Please drop this except KeyError.
There was a problem hiding this comment.
Dropped the KeyError exception handler so missing session users fail loudly as before.
| monkeypatch.setattr(site_proxy, "pwd", None) | ||
| assert site_proxy.serve_user("agent") == "agent" | ||
| assert site_proxy.trust_nss("agent", "/fake/ca.pem") == [] | ||
| site_proxy.drop_privileges("agent") |
There was a problem hiding this comment.
Nothing is asserted after this call, so the test only shows that it doesn't raise. If the hasattr guards are removed as suggested above, this line goes too.
There was a problem hiding this comment.
Removed along with the runtime guards.
| site_proxy.drop_privileges("agent") | ||
|
|
||
|
|
||
| def test_the_proxy_imports_when_pwd_is_unavailable(monkeypatch): |
There was a problem hiding this comment.
Reloading site_proxy partway through the suite swaps out the module's classes. After the reload, site_proxy.Config is not the Config this file imported at the top. I saw no failures locally (the file and the rest of tst/unit/env/envs pass), but this is fragile. If the import guard is the only change left, running python -c in a subprocess with sys.modules['pwd'] = None tests the fresh import without reloading the module in the test process.
There was a problem hiding this comment.
Updated to run the fresh import assertion in an isolated subprocess (python -c) without in-process reloads.
…oxy import in subprocess
|
Thanks for the detailed review and guidance @andrewpark-scaleai. Updated the branch with the following changes:
|
The local store already skips fcntl on Windows, and serve_user runs only as root inside a Linux computer, where pwd exists, so both go back to main's code. The test imports sites, the host's import of the proxy, with pwd blocked. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
On which platform hit this: a native Windows host. On Windows 11 with 0.9.1474, every On What I pushed (c099ad5, a merge of
The description is updated to match, including that this makes agent-env importable on Windows, not a supported host. |
What and why
On Windows,
agent-envcouldn't even start: every command,--helpincluded, failed withModuleNotFoundError: No module named 'pwd'.site_proxy.pyimportedpwd, which is Unix-only, at module level. The host imports it throughsites.py, which takesis_localandmatches, andsites.pyis imported by the bundle planner and the built-in website and multi-server envs.This change guards that one import (
pwd = Noneon Windows), asbundle/_fs.pyalready does for its ownpwdandfcntl. Nothing else changes:serve,drop_privileges,installandtrust_nssrun only as root inside the Linux computer, wherepwdexists, and still fail loudly as before. The local object store already skipsfcntlon Windows, so it needs no change.is_localandmatchesstay insite_proxy.py. The proxy runs inside the computer as one standalone file on the base's ownpython3and uses both itself, so moving them would mean keeping two copies.This makes agent-env importable on Windows. It doesn't make Windows a supported host:
pyproject.tomllists macOS and Linux.How it was tested
agent-env --help,config show,env --helpandrun --helpall exited 1 onNo module named 'pwd', and so did importingagent_env.cli,sites,bundle.plan, the website and multi-server envs, andrun_code;test_the_proxy_imports_when_pwd_is_unavailableimportssite_proxyandsitesin a fresh interpreter withpwdblocked. It fails againstmainand passes with the guard.tst/unit/env/envs: 829 passed. Ruff is clean.🤖 Generated with Claude Code


Confidence Score: 5/5
The PR appears safe to merge; no actionable new issues were found.Summary
Guards the
pwdimport so host-side helpers can load without that Unix-only module.pwdis unavailable.Reviews (4) · Last reviewed commit: "Merge main; keep only the guard on site_..." · Reviewed by Greptile