mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-10-26 21:26:39 +00:00
* fix(sandbox): exempt awk field arithmetic from the shell-variable path guard Since #6930 every `$NAME/` in a host-bash command was treated as a variable-prefixed host path unless both sides were digits, so legitimate awk programs such as `awk '{print $NF/2}' data.txt` or `awk '{print $sum/$n}' data.txt` on files under /mnt/user-data were rejected with "Unsafe absolute paths". Exempt a `$` only inside the single-quoted inline program of awk, gawk, mawk or nawk (after `-F`, `-v` and `--`), where bash expands nothing and awk reads `$NAME` as a field reference. awk string literals, option values, input operands, double-quoted programs, text re-read by `sh -c` or `eval`, heredocs, awk functions/aliases, unknown options such as gawk's `--assign`, `-f` programs, and programs whose `"` may sit in a regex or comment keep the strict scan. Fixes bytedance/deer-flow#7021 * fix(sandbox): read awk string literals and comments before judging quotes Review follow-up: the quote-reliability check gave up the awk exemption for any `/` not preceded by an identifier, number or `]`, including a `/` inside a plain string literal, so `awk '{n=split($0,p,"/"); print $1/p[n]}'` was still rejected. Walk the program once with the same string-literal tracker that computes the code spans: `/` and `#` inside a literal are text, `#` outside one starts a comment to end of line, and only a `/` outside a literal that cannot be division (regex literal) forfeits the exemption. * fix(sandbox): scan the awk exemption the way the shell parses the command Review follow-up for the awk field-arithmetic exemption. Bypasses closed: a backslash-newline let `aw\<nl>k() { eval "$1"; }` define an awk function past the literal blocker regex, so any continuation now forfeits the exemption; the word scanner emitted `)`, `$(` and `>|` as command separators, so an `awk` that was only an argument (`echo $(true) awk '...'`) looked like a command; `$'...'`, comments and quotes nested in `"$(...)"` could desynchronise quote pairing; the alias/function blocker only matched literal spellings and ignored eval, source, hash, PATH, autoload and zsh's `functions[awk]=` / `aliases[awk]=` arrays. The scanner now follows bash: single and double quotes with escapes, `#` comments at a word start, fd redirections, the usual separators, and `$(...)` as a nested command context with fresh quoting. Anything it does not model (backslash-newline, backticks, `$'...'`, heredocs, an unmatched `)`, unbalanced quotes) returns no exemption. The command word is found like `_validate_local_bash_shell_tokens` finds it: after assignments, prefix keywords and wrappers, reduced to its basename, inside every `$(...)`. A command that could redefine awk or re-read quoted text gets no exemption at all, and the docstring says the enumeration is best-effort. False positives removed: `($2+$3)/2` and `length($0)/2` (a `/` after `)` is division unless the `)` closes an if/while/for condition, and the absolute-path scan is now exempt inside awk code too), `/usr/bin/awk`, `LC_ALL=C awk`, `echo "$(awk ...)"`, `"<<"` inside an awk string. The awk spans are computed lazily, only when a `$NAME/` or absolute-path match needs them, and the division check scans backward instead of re-slicing the program. * fix(sandbox): exempt only single-segment absolute-path matches in awk code Review follow-up. Inside awk code spans the absolute-path scan now skips only a match with no second `/` (`/2`, `/n`, `/NR`), so a `/a/b` shape is still rejected even if a span were ever misjudged; previously `awk '{print ($1)/etc/passwd}'` and `awk 'BEGIN{x = 1 /etc/shadow}'` were accepted. `enable` joins the commands that withhold the exemption, since `enable -f` can load a builtin under any name. The division check reads the preceding `)` through the backward scan instead of re-slicing the program for every `/`. --------- Co-authored-by: Willem Jiang <willem.jiang@gmail.com>