Commit 229add9
t2wei
fix(exec): allow symlinked OPENCLAW_STATE_DIR via terminal stat
`ensureDir` validated the approvals directory with `fs.lstatSync`, then
rejected any path where `isSymbolicLink()` was true. This breaks on
common deployment topologies where the state directory itself is a
top-level symlink (e.g. `/opt/openclaw` -> `/mnt/efs/openclaw` for
EFS-backed hosts on AWS).
The companion `assertNoExecApprovalsSymlinkParents` check walks the
segments BETWEEN the trusted root and the terminal target — when
`OPENCLAW_STATE_DIR` equals `OPENCLAW_HOME` (the trusted root), no
segments are walked and the terminal symlink slips past that walk
without inspection. The follow-up lstat check is therefore the only
gate, and it rejects the entire deployment.
Switch to `fs.statSync` so a terminal symlink that resolves to a real
directory is accepted while:
- intermediate path symlinks are still rejected by the parents check
- non-directory terminals (regular files, FIFOs, etc.) are still
rejected via `dirStat.isDirectory()`
Symptom before fix:
```text
[tools] exec failed: Refusing to use unsafe exec approvals directory:
/opt/openclaw raw_params={"workdir":"...","timeout":20}
```
Every exec tool call from any agent failed with the same error
regardless of `workdir`, because `OPENCLAW_STATE_DIR` resolution
happens server-side before the workdir is consulted.
Adds a regression test that mirrors the deployment shape: `HOME` and
`STATE_DIR` both pointing at a symlink whose target is a real directory.1 parent a0f93cf commit 229add9
2 files changed
Lines changed: 34 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
338 | 338 | | |
339 | 339 | | |
340 | 340 | | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
341 | 365 | | |
342 | 366 | | |
343 | 367 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
418 | 418 | | |
419 | 419 | | |
420 | 420 | | |
421 | | - | |
422 | | - | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
423 | 431 | | |
424 | 432 | | |
425 | 433 | | |
| |||
0 commit comments