Skip to content

fix(fuzz): drop glob_fuzz inputs that contain banned debug shapes#1621

Merged
chaliy merged 1 commit into
mainfrom
fix/glob-fuzz-input-filter
May 9, 2026
Merged

fix(fuzz): drop glob_fuzz inputs that contain banned debug shapes#1621
chaliy merged 1 commit into
mainfrom
fix/glob-fuzz-input-filter

Conversation

@chaliy
Copy link
Copy Markdown
Contributor

@chaliy chaliy commented May 9, 2026

Summary

The nightly fuzz job on main is red. glob_fuzz inlines fuzz input directly
into ls /tmp/{input}, case ... in {input}), and [[ ... == {input} ]],
so any unmatched path is echoed verbatim by the shell/ls in stderr.

Last run: input ==(Span {(; produced ls: cannot access '/tmp/==(Span {(;',
which contains the banned Span { shape — but no internal Debug formatter ran,
this is real-shell-style stderr.

Fix: at the fuzz-input layer, drop inputs that already contain any
UNIVERSAL_BANNED substring. This keeps TM-INF-022 detection strict on real
builtin internals while removing the false-positive class.

Test plan

  • cargo check on the fuzz crate compiles cleanly
  • Manually dispatch Fuzz Testing on this branch and confirm glob_fuzz job is green

Generated by Claude Code

Inputs are inlined into ls/case/[[ ]] commands; an unmatched path is
echoed verbatim by the shell, so a user-supplied 'Span {' tripped
TM-INF-022 even though no internal Debug formatter ran. Filter at the
fuzz-input layer keeps the leak detector strict on real internals.
@cloudflare-workers-and-pages
Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
bashkit 40019de Commit Preview URL

Branch Preview URL
May 09 2026, 09:08 AM

@chaliy chaliy merged commit 4206b93 into main May 9, 2026
24 checks passed
@chaliy chaliy deleted the fix/glob-fuzz-input-filter branch May 9, 2026 09:20
chaliy added a commit that referenced this pull request May 10, 2026
…pe check (#1623)

## Summary

When a fuzz/proptest target inlines arbitrary input bytes into a shell
script, bash and ls produce error messages that quote the input
verbatim:

```
bash: <cmd>: command not found
bash: <path>: No such file or directory
ls:   cannot access '<path>': No such file or directory
```

These echoes can accidentally form a banned substring even when no
internal Debug formatter ran. Two real cases:

- arithmetic_fuzz / glob_fuzz: input contained `/.rustup/toolchains/`
literally; bash echoed it back. Filtered at the input layer in #1621 and
#1622.
- **glob_fuzz (new, dispatched run on this branch):** input ended with
`Tok"`. Bash treated `Tok:` as a command and rendered `bash: Tok::
command not found` — the trailing `:` chrome from bash's error format
glued onto the input's final `:` to form the banned parser-token shape
`Tok::`. Pre-filtering the input for `Tok::` doesn't catch this — the
substring only forms after bash's formatter runs.

## Fix

Structural fix in `assert_fuzz_invariants`: strip lines that match a
recognized real-shell error template before running the banned-shape
check.

- Byte-length cap (`MAX_STDERR_BYTES`) still runs on the **unfiltered**
stderr — flood regressions still caught.
- Host-canary check (TM-INF-013) still runs on the unfiltered stderr —
env-leak regressions still caught.
- The strict `assert_no_leak` path (used by per-builtin tests) is
unchanged — non-fuzz tests must not produce shell echoes in the first
place.

Recognized templates are conservative: prefix `bash: ` or `ls: ` plus a
known suffix. Lines that look similar but don't match the exact template
stay in stderr, so real Debug leaks that happen to coexist with shell
errors still trip the assertion.

## Test plan

- [x] 8 unit tests in `testing::tests` cover both directions — strip
known shell echoes, keep internal panic/Debug lines, keep partial
matches and lines from other tools.
- [x] `cargo test -p bashkit --lib testing::` green
- [x] `cargo test -p bashkit --test proptest_security --all-features`
green (18 cases)
- [x] `cargo clippy -p bashkit --lib --tests -- -D warnings` clean
- [x] `cargo fmt --check` clean
- [x] Threat-model TM-INF-022 section updated to document the carve-out
- [ ] Manually dispatch `Fuzz Testing` on this branch and confirm
`glob_fuzz` job is green
yonas pushed a commit to yonasBSD/bashkit that referenced this pull request May 11, 2026
…es (everruns#1622)

## Summary

The nightly fuzz job on main is red. `arithmetic_fuzz` inlines fuzz
input directly into `echo \$(({input}))`. With unbalanced parens the
arithmetic expansion closes early and the remainder is parsed as
commands; bash then echoes the unknown command verbatim (`bash:
/.rustup/toolchains/gww: No such file or directory`). That is real-shell
stderr, not a TM-INF-022 leak.

Last run: input bytes contained `/.rustup/toolchains/` literally and the
fuzz harness's leak detector tripped on the banned host-path shape — but
no internal Debug formatter ran.

Fix: at the fuzz-input layer, drop inputs that already contain any
`UNIVERSAL_BANNED` substring. Mirrors everruns#1621 for `glob_fuzz`.

## Test plan

- [x] `cargo check` on the fuzz crate compiles cleanly
- [ ] Manually dispatch `Fuzz Testing` on this branch and confirm
`arithmetic_fuzz` job is green
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant