Commit 48d09e4
Fix six defects found by the final red-team, four of them mine
**Single-venv jobs could never return a result (critical, introduced by me).**
Result signing was added to the two-venv branch only, while the submitter
recorded a signing key unconditionally -- so any job that fell back to the
single-venv path (use_two_venv=False, or any two-venv setup failure or
timeout) produced a result the caller then refused as unsigned. A degraded but
working path became a hard failure. All four schedulers now sign on both
branches, via one shared `result_signing_lines()` so a branch cannot forget
again.
Testing that on tensor01 uncovered three more, each hidden behind the last:
* **The SSH fallback never built its venv.** Both of its fallback branches set
`venv_info = None` and stopped; the SLURM path has always called
`setup_remote_environment`. The generated script therefore activated a
virtualenv nobody had created: "venv/bin/activate: No such file or
directory".
* **`python -m venv` assumed a `python` that does not exist.** Python 3
installs ship `python3`; `python` is only present where somebody added a
compatibility symlink. `resolve_remote_python` now probes.
* **The dill install was best-effort.** `|| echo 'Package installation failed,
continuing...'` swallowed the failure of the one package the job script
cannot work without, and the job died twenty lines into a remote traceback
with "'NoneType' object is not callable", naming neither.
Which finally exposed the real limit, which is not papered over: **the
single-venv path cannot bridge Python versions at all.** dill embeds CPython
bytecode, so a 3.12 payload on tensor01's `python3 (3.6.8)` gives
"code() takes at most 15 arguments (20 given)". It now fails at submit time
with something actionable:
No python3.12 on the remote host, and dill payloads cannot cross Python
minor versions. Found: python3 (3.6.8). Either install python3.12 there,
set python_executable to a matching interpreter, or leave use_two_venv
enabled so clustrix can build a conda environment at the right version.
**Silent chmod failure -> key theft -> code execution on the submitting
machine.** `execute_remote_command` never checked exit status, and job
directories were `job_<unix_seconds>` -- fully predictable. On a
world-writable remote_work_dir an attacker could pre-create the directory;
`mkdir -p` succeeds on it, the unchecked `chmod 700` fails unnoticed, the
signing key lands somewhere they can read, and they forge both result.pkl and
its HMAC. Directories are now created exclusively with `mkdir -m 700` and the
status checked, and their names carry four random bytes -- which also fixes
two jobs submitted in the same second overwriting each other's key.
**`1.5GB` produced `--mem=1.5G`**, which SLURM and PBS reject. Fractional
sizes round up (down would get the job killed).
Shell interpolations of config-derived paths are now `shlex.quote`d.
The agent also attacked and could not break: `make_portable_function` (its
source is a module constant), the HMAC's coverage of the downloaded bytes,
`compare_digest`'s operands, cleanup ordering, and the dropdown reentrancy
guard.
All three backends re-verified afterwards:
slurm PASSED t08.hpcc.dartmouth.edu python 3.12.13
gpu PASSED tensor01.dartmouth.edu python 3.12.13
hf PASSED j-contextlab-6a8401ce... python 3.12.14
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012gTBDPK16HUZ3kHQ2QyjuU1 parent 4346a10 commit 48d09e4
4 files changed
Lines changed: 189 additions & 128 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
217 | 217 | | |
218 | 218 | | |
219 | 219 | | |
220 | | - | |
221 | | - | |
| 220 | + | |
| 221 | + | |
| 222 | + | |
| 223 | + | |
| 224 | + | |
| 225 | + | |
| 226 | + | |
| 227 | + | |
| 228 | + | |
222 | 229 | | |
223 | 230 | | |
224 | 231 | | |
225 | 232 | | |
226 | 233 | | |
227 | | - | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
228 | 243 | | |
229 | 244 | | |
230 | 245 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| |||
190 | 191 | | |
191 | 192 | | |
192 | 193 | | |
193 | | - | |
| 194 | + | |
194 | 195 | | |
195 | 196 | | |
196 | 197 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
6 | 6 | | |
7 | 7 | | |
8 | 8 | | |
| 9 | + | |
9 | 10 | | |
10 | 11 | | |
11 | 12 | | |
| |||
42 | 43 | | |
43 | 44 | | |
44 | 45 | | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
45 | 53 | | |
46 | | - | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
47 | 58 | | |
48 | 59 | | |
49 | 60 | | |
| |||
73 | 84 | | |
74 | 85 | | |
75 | 86 | | |
76 | | - | |
| 87 | + | |
77 | 88 | | |
78 | 89 | | |
79 | 90 | | |
| |||
198 | 209 | | |
199 | 210 | | |
200 | 211 | | |
201 | | - | |
| 212 | + | |
202 | 213 | | |
203 | 214 | | |
204 | 215 | | |
| |||
245 | 256 | | |
246 | 257 | | |
247 | 258 | | |
248 | | - | |
| 259 | + | |
249 | 260 | | |
250 | 261 | | |
251 | 262 | | |
| |||
302 | 313 | | |
303 | 314 | | |
304 | 315 | | |
305 | | - | |
| 316 | + | |
306 | 317 | | |
307 | 318 | | |
308 | 319 | | |
| |||
368 | 379 | | |
369 | 380 | | |
370 | 381 | | |
371 | | - | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
372 | 394 | | |
373 | 395 | | |
374 | 396 | | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
375 | 403 | | |
376 | 404 | | |
377 | 405 | | |
| |||
0 commit comments