Skip to content

Fix the weekly fuzz runs and the BESL leaks they found - #58

Merged
facundo-villa merged 5 commits into
devfrom
claude/weekly-fuzz-ci-0r5z69
Sep 27, 2026
Merged

facundo-villa merged 5 commits into
devfrom
claude/weekly-fuzz-ci-0r5z69

Conversation

@facundo-villa

@facundo-villa facundo-villa commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

Requested by Facundo · project thread

Before: every job in the first scheduled Fuzz BESL and Fuzz BETP runs failed in about 2 seconds with sanitizer is incompatible with statically linked libc, before any fuzzing happened. The fuzz workflows rebuilt every dependency each run. Once fuzzing ran, the BESL compile target reported memory leaks for main: fn () -> root {}, recursive functions, and vec3f(main) inside main.

After: the fuzz targets build for x86_64-unknown-linux-gnu and fuzz normally, with a cached build. All three leaking inputs compile without leaking. Recursion still links. A type name that isn't a type, and a function used as a value, are now lexer errors.

How:

  • Build target. taiki-e/install-action falls back to cargo-binstall, which installs the prebuilt musl cargo-fuzz. cargo-fuzz defaults --target to its own triple, and AddressSanitizer can't link static musl libc. Both workflows pass --target x86_64-unknown-linux-gnu.
  • Build cache. Each fuzz job caches the Cargo registry and its fuzz target directory with actions/cache (backed by Blacksmith), keyed on the fuzz workspace's Cargo.lock, like rust.yml.
  • Type names. resolve_type accepted any named node, so -> root made main hold its own ancestor. It now accepts only Struct declarations.
  • Weak call references (breaking). Expressions::FunctionCall::function is now a CallTarget. It holds a Weak reference to Function nodes and a strong one to anything else, such as type constructors and on-demand array types the call may solely own. Read it with CallTarget::get(). The program tree now owns every function, so keep the program alive while you use its main. The test fixtures that returned main and dropped the program now return the program.
  • Functions as values. A bare function name in value position is now LexError::Undefined, because it formed the same cycle.

Validation: byte-engine-besl has 219 lib tests, and byte-engine-resource-management has 628 lib and 12 integration tests; all pass. New lexer tests cover non-type names, functions as values, and recursive calls. cargo fmt --check reports no new diffs. Each saved leak input runs clean under ASan.

Known remaining: a 5-minute local compile fuzz run found a parser timeout, not a leak. A 269-byte input of deeply nested unbalanced calls takes about 6 seconds to parse under ASan. It is in the parser, which this PR doesn't touch.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BYDnECscGCTZr5M5upFEMs

install-action installs a prebuilt musl cargo-fuzz, which then builds the
fuzz targets for x86_64-unknown-linux-musl. AddressSanitizer rejects the
statically linked musl libc, so every fuzz job failed before fuzzing.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BYDnECscGCTZr5M5upFEMs
@facundo-villa facundo-villa self-assigned this Sep 27, 2026
Each fuzz job now caches the Cargo registry and its fuzz target directory,
keyed on the fuzz workspace lockfile, the same way rust.yml caches the
engine build.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BYDnECscGCTZr5M5upFEMs
@facundo-villa facundo-villa changed the title Pin the glibc target for weekly fuzz runs Fix and cache the weekly fuzz runs Sep 27, 2026
A type annotation such as `-> root` resolved to the program's root scope,
because type lookup accepted any named node. The function then held a
strong reference to its own ancestor, and the Rc cycle leaked the whole
tree. The BESL compile fuzz target reported this as a leak.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BYDnECscGCTZr5M5upFEMs
@facundo-villa facundo-villa changed the title Fix and cache the weekly fuzz runs Fix and cache the weekly fuzz runs, and fix a BESL type-name leak Sep 27, 2026
A FunctionCall held a strong reference to the function it calls. A
recursive call sits inside the function's own statements, so the tree
formed an Rc cycle and was never freed. The BESL compile fuzz target
reported these leaks.

FunctionCall now stores a CallTarget: a weak reference for Function
nodes, and a strong one for type constructors and on-demand array types
that the call may be the only owner of. Read it with CallTarget::get.
The program tree now owns every function, so callers keep the program
alive while they use its main function.

Functions used as values, such as `vec3f(main)` inside main, are now a
lexer error, since they formed the same cycle.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BYDnECscGCTZr5M5upFEMs
@facundo-villa facundo-villa changed the title Fix and cache the weekly fuzz runs, and fix a BESL type-name leak Fix the weekly fuzz runs and the BESL leaks they found Sep 27, 2026
Both workflows ran the same steps on the same schedule and differed only
in crate and target list. One matrix over crate and target keeps a single
place to change cargo-fuzz setup, caching, and artifacts, and job names
still show which crate and target failed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BYDnECscGCTZr5M5upFEMs
@facundo-villa
facundo-villa marked this pull request as ready for review September 27, 2026 19:26
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-27T19:30:29.868598Z 918a310 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@facundo-villa
facundo-villa merged commit 3eb298d into dev Sep 27, 2026
7 of 8 checks passed
@facundo-villa
facundo-villa deleted the claude/weekly-fuzz-ci-0r5z69 branch September 27, 2026 20:42
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.

2 participants