Disclosure summary
### Summary `Oj::Doc` iterators (`each_value`, `each_child`, `each_leaf`) are vulnerable to a heap use-after-free. When a Ruby block yielded during iteration calls `doc.close` or `d.close`, the document's heap memory is freed while the C iterator is still running. When control returns from the block, the iterator reads from the freed region, producing a use-after-free accessible from pure Ruby. ### Version - **Software**: oj gem - **Affected**: all versions with `ext/oj/fast.c` - **Latest tested**: 3.17.1 (confirmed present) ### Details The iterators in `ext/oj/fast.c` follow the pattern: ```c // fast.c:1505 (doc_each_child) static VALUE doc_each_child(VALUE self, ...) { ... while (cur != NULL) { rb_yield(...); // ← Ruby block executes here cur = cur->next; // ← cur is now freed if block called close() } } ``` `rb_yield` can invoke arbitrary Ruby code, including calling `close()` on the `Doc` or any child node, which calls `ruby_sized_xfree` on the backing buffer. On return, the C code reads `cur->next` from the freed region. All three iterators are affected. ASAN report (each_child variant): ``` ==253632==ERROR: AddressSanitizer: heap-use-after-free on address 0x5210000bd080 READ
Source-specific records & product guidance
Sources retain their own attribution and scoring. Follow the original record to confirm affected versions, fixed releases, and configuration conditions.
GitHub Reviewed Security Advisories · GHSA-9ppp-w3g4-fh4q
Open original source · Updated Oct 06, 2026
Oj: Use-After-Free in Oj::Doc Iterators via Reentrant Close
Source severity: HIGH / 8.7
| Ecosystem | Package | Affected range | First patched |
|---|---|---|---|
| rubygems | oj | 3.17.3 |
Original records & references
- NIST NVD record
- CVE Program record
- github.com — Reviewed advisory
PUBLISHED 2026-06-19T15:36:50-04:00
MODIFIED 2026-10-06T15:50:14-04:00
INGESTED 2026-10-08T12:05:11-04:00