Skip to content

bundler: post Bun.build completions by ScriptExecutionContext id to survive worker.terminate() - #35158

Closed
robobun wants to merge 7 commits into
mainfrom
farm/7993167a/bundle-worker-uaf
Closed

bundler: post Bun.build completions by ScriptExecutionContext id to survive worker.terminate()#35158
robobun wants to merge 7 commits into
mainfrom
farm/7993167a/bundle-worker-uaf

bundler: post Bun.build completions by ScriptExecutionContext id to s…

f7901f3
Select commit
Loading
Failed to load commit list.
Claude / Claude Code Review completed Jul 22, 2026 in 13m 14s

Code review found 1 important issue

Found 5 candidates, confirmed 3. See review comments for details.

Details

Severity Count
🔴 Important 1
🟡 Nit 2
🟣 Pre-existing 0
Severity File:Line Issue
🔴 Important src/bundler/BundleThread.rs:231-240 is_owner_alive() TOCTOU: env loader can still be freed between check and use
🟡 Nit test/bundler/bun-build-api.test.ts:1566-1567 Test asserts on absence of crash strings in stderr (CLAUDE.md violation)
🟡 Nit src/runtime/api/js_bundle_completion_task.rs:62-64 Dead jsc_event_loop field left behind after switching to context_id

Annotations

Check failure on line 240 in src/bundler/BundleThread.rs

See this annotation in the file changed.

@claude claude / Claude Code Review

is_owner_alive() TOCTOU: env loader can still be freed between check and use

The `is_owner_alive()` pre-check is a check-then-act TOCTOU that narrows but does not close the env-loader UAF: `ScriptExecutionContext__isAlive` releases the contexts-map lock before `generate_in_new_thread` runs, so nothing prevents the worker from calling `markTerminating()` and freeing `env_loader` (web_worker.rs:1401) between the check and `Transpiler::init` writing through it — and once the bundle is running, `resolver.env_loader` is held and dereferenced (e.g. the `NODE_PATH` lookup at re

Check warning on line 1567 in test/bundler/bun-build-api.test.ts

See this annotation in the file changed.

@claude claude / Claude Code Review

Test asserts on absence of crash strings in stderr (CLAUDE.md violation)

These two `.not.toContain` assertions on "use-after-free" / "Segmentation fault" are the pattern CLAUDE.md explicitly forbids ('NEVER write tests that check for no "panic" or "uncaught exception" or similar in the test output. These tests will never fail in CI.'). The load-bearing checks — `expect(stdout.trim()).toBe("OK " + rounds)` and `expect(exitCode).toBe(0)` two lines below — already catch a SIGSEGV/ASAN abort; drop these two lines (or fold everything into a single `expect({ stdout, stderr

Check warning on line 64 in src/runtime/api/js_bundle_completion_task.rs

See this annotation in the file changed.

@claude claude / Claude Code Review

Dead jsc_event_loop field left behind after switching to context_id

After rerouting both consumers to `context_id.post_concurrent_task`, nothing reads `jsc_event_loop` anymore — the field, its now-false doc comment ('call sites read `self.jsc_event_loop.enqueue_task_concurrent(..)`'), and the `event_loop: *mut EventLoop` parameter of `create_and_schedule_completion_task` (now used only to populate this dead field) should be removed in this PR. The stale comments at `src/bundler/bundle_v2.rs:1504` and `src/bundler/BundleThread.rs:85` referencing `jsc_event_loop.e