# Reentrancy frees buffer held across callback

Pointer or length cached before a callback that can realloc or free the same buffer

_Area: Memory corruption and native code. Seen in 4 disclosed reports; one confirmed bounty: $800; latest 2026-08-05. Updated 2026-11-08._

## How it works
Code reads a pointer, length, or struct field from a container, then calls something that can run user code (argument coercion, `to_str`/`to_i`, `ensure`/`rescue`, recursive `unserialize`, `method_missing`). That callback reallocates or frees the same backing memory. The original pointer or cached length is now stale, and the next dereference or write hits freed or moved memory. The broken assumption: "nothing I call can change the object I am holding."

## Where it shows up
- Native methods that cache length/pointer, then call an argument-conversion helper (`mrb_get_args`, `to_i`, `to_str`) [E3](https://bugbountylibrary.com/r/h1%3A181893.md).
- Exception, `ensure`, and `rescue` paths that realloc interpreter stacks while a frame still holds `ci->proc` or similar [E1](https://bugbountylibrary.com/r/h1%3A213261.md).
- Recursive parsers (legacy `Serializable::unserialize`) that re-enter without a lock and share one reference/bucket table [E2](https://bugbountylibrary.com/r/blog%3Ablog-calif-io-p-the-wordpress-chain-massacre.md).
- `inspect`/`to_s`/string-cat paths that realloc while a self-referential object is being walked [E4](https://bugbountylibrary.com/r/h1%3A192532.md).
- Any `prepend`/`instance_eval`/`method_missing` self-reference that re-enters the same buffer [E4](https://bugbountylibrary.com/r/h1%3A192532.md).

## How to review
For each function, list every call that can re-enter user code. Between the cache and the use, ask: can this call free or realloc the buffer? The invariant: a pointer or length must be re-read after any re-entrant call, or the buffer must be pinned/refcounted for the whole window. Check that parsers take a lock before recursing [E2](https://bugbountylibrary.com/r/blog%3Ablog-calif-io-p-the-wordpress-chain-massacre.md), and that coercion happens before length is cached [E3](https://bugbountylibrary.com/r/h1%3A181893.md).

## How finders spotted it
- Noticed `setbyte` cached length before `mrb_get_args`, and that conversion can call back into Ruby, opening a TOCTTOU window [E3](https://bugbountylibrary.com/r/h1%3A181893.md).
- Fuzzed unusual constructs (`to_str` + `ensure` + `rescue` + `Struct`); gdb and Valgrind showed invalid reads/writes in realloc-freed memory [E1](https://bugbountylibrary.com/r/h1%3A213261.md).
- Reasoned that PHP-level guards box execution, so hunted a memory bug reachable from pure PHP; picked a UAF for arbitrary-read plus fake-object primitives [E2](https://bugbountylibrary.com/r/blog%3Ablog-calif-io-p-the-wordpress-chain-massacre.md).
- Experimented with `prepend`/`instance_eval`/`method_missing` self-reference; gdb backtraces ran through `mrb_str_inspect` realloc [E4](https://bugbountylibrary.com/r/h1%3A192532.md).

## Variants seen
- Exception/`ensure` realloc frees `callinfo`, later dereferenced [E1](https://bugbountylibrary.com/r/h1%3A213261.md).
- Argument coercion shrinks string after length cached, out-of-bounds write [E3](https://bugbountylibrary.com/r/h1%3A181893.md).
- Recursive unserialize shares reference table; inner resize frees outer buckets [E2](https://bugbountylibrary.com/r/blog%3Ablog-calif-io-p-the-wordpress-chain-massacre.md).
- Self-referential prepend corrupts string-buffer heap metadata [E4](https://bugbountylibrary.com/r/h1%3A192532.md).

## Impact and severity
Crashes (DoS) in the sandbox [E1](https://bugbountylibrary.com/r/h1%3A213261.md)[E4](https://bugbountylibrary.com/r/h1%3A192532.md); heap corruption with attacker-influenced structs, potentially hijacking execution [E1](https://bugbountylibrary.com/r/h1%3A213261.md). In E2 the UAF gave arbitrary read and fake objects, chained to native code execution bypassing `disable_functions` and read-only mounts, then a page-cache LPE to root. Impact rose with chaining and with reach into a privileged interpreter [E2](https://bugbountylibrary.com/r/blog%3Ablog-calif-io-p-the-wordpress-chain-massacre.md).

## Seen in real software
Open-source packages and projects, and products, where this pattern was found. If the target runs one, compare the version it runs with the fix.
- **PHP** (legacy Serializable unserialize path) (version not stated): The WordPress Chain Massacre. Report: https://bugbountylibrary.com/r/blog%3Ablog-calif-io-p-the-wordpress-chain-massacre.md

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A213261.md
- E2: https://bugbountylibrary.com/r/blog%3Ablog-calif-io-p-the-wordpress-chain-massacre.md
- E3: https://bugbountylibrary.com/r/h1%3A181893.md
- E4: https://bugbountylibrary.com/r/h1%3A192532.md
