Files
Takashi Kokubun 599ed107f1 YJIT: Fix version_map use-after-free from mutable aliasing UB
Multiple YJIT functions created overlapping `&'static mut IseqPayload`
references by calling `get_iseq_payload()` multiple times for the same
iseq. LLVM's noalias optimizations could then cache stale version_map
Vec headers, causing the version_map to point to freed backing storage.

This manifested as crashes in various YJIT operations (block lookup,
GC marking, block removal) that dereference the stale pointer.

Fix by moving `delayed_deallocation` and `get_or_create_version_list`
from free functions (which each call `get_iseq_payload()` internally)
to methods on `IseqPayload` that operate through `&mut self`. This
lets callers obtain a single payload reference and use it for all
operations without creating overlapping mutable borrows.

The three fixed call sites:

1. `rb_yjit_tracing_invalidate_all` (invariants.rs): The loop called
   `delayed_deallocation()` which internally called `get_iseq_payload()`,
   creating a second `&mut` overlapping with the outer `payload` reference.
   Fix: call `payload.delayed_deallocation()` method instead.

2. `add_block_version` (core.rs): Called `get_or_create_version_list()`
   then later `get_iseq_payload()` for pages, creating two references.
   Fix: use a single `get_or_create_iseq_payload()` call then call the
   `get_or_create_version_list()` method on it for both version_map and
   pages access.

3. `invalidate_block_version` (core.rs): Called `remove_block_version()`
   (which calls `get_iseq_payload()`) then `delayed_deallocation()`
   (which also calls `get_iseq_payload()`), creating two references.
   Fix: get the payload once, inline the version_map removal, and call
   `payload.delayed_deallocation()` method for the rest.

Also adds regression tests exercising tracing invalidation with
on-stack methods and suspended fibers.

(cherry picked from commit a6fcad276a)
2026-07-09 22:51:30 +09:00
..
2020-04-27 10:39:07 +09:00
2024-06-03 16:50:43 -07:00
2022-04-27 11:00:22 -04:00