Skip to content

bun:ffi: throw when calling a symbol after close() instead of jumping into freed JIT memory - #29946

Closed
robobun wants to merge 10 commits into
mainfrom
farm/9ef4a177/ffi-close-uaf
Closed

bun:ffi: throw when calling a symbol after close() instead of jumping into freed JIT memory#29946
robobun wants to merge 10 commits into
mainfrom
farm/9ef4a177/ffi-close-uaf

Fix dlopen .failed branch: run deinit loop before clearAndFree, not a…

4e34f76
Select commit
Loading
Failed to load commit list.
Claude / Claude Code Review completed May 4, 2026 in 32m 50s

Code review found 1 potential issue

Found 1 candidates, confirmed 1. See review comments for details.

Details

Severity Count
🔴 Important 0
🟡 Nit 1
🟣 Pre-existing 0
Severity File:Line Issue
🟡 Nit src/runtime/ffi/ffi.zig:1174 cb.protect() is only balanced via close(); never-closed libs leak permanent GC roots and break CFunction auto-close

Annotations

Check warning on line 1174 in src/runtime/ffi/ffi.zig

See this annotation in the file changed.

@claude claude / Claude Code Review

cb.protect() is only balanced via close(); never-closed libs leak permanent GC roots and break CFunction auto-close

Minor follow-up: the new `cb.protect()` here (and at lines 819/1281) is only balanced by `unprotect()` inside `Function.deinitWithoutGlobal()`, which is reached via `close()` or error-unwind but never via GC — `FFI.finalize()` (line 69) is an empty no-op. So a library that is simply dropped without calling `close()` now also leaks one permanent `gcProtect` root per symbol on top of the pre-existing native (TCC.State / FFI struct / dylib handle) leak on that same path. Not blocking — the incremen