# Runtime rebinding breaks type assumption

Core classes, constants or state rebound at runtime, then used as the original type without revalidation

_Area: Memory corruption and native code. Seen in 3 disclosed reports; 2 confirmed bounties: $1,000 and $10,000; latest 2016-12-17. Updated 2026-11-01._

## How it works
Code assumes a name (a class constant, an exception class, a stored field) still refers to the type it meant when written. If that name is resolved at runtime and user code can rebind it, the object built or passed is of a different type than the code that consumes it expects. The consumer then reads fields at the wrong offsets or calls function pointers that do not exist, giving type confusion and memory corruption. The broken assumption is "this identifier is fixed"; the fix is to cache the reference or revalidate the type at the point of use.

## Where it shows up
- Core constructors that look up a class by name at runtime instead of using a cached pointer held in interpreter state [E1](https://bugbountylibrary.com/r/h1%3A181910.md).
- Macros or helpers that expand to a runtime class lookup (error/exception constructors) rather than a constant [E3](https://bugbountylibrary.com/r/h1%3A185041.md).
- C-extension `setstate`/deserialization paths that parse a tuple and store fields without a type check [E2](https://bugbountylibrary.com/r/h1%3A175091.md).
- Any struct field later passed to a function expecting a specific type (iterator, exception, range) with no check at store or use time [E2](https://bugbountylibrary.com/r/h1%3A175091.md)[E3](https://bugbountylibrary.com/r/h1%3A185041.md).
- Sibling functions in the same module that do validate — a gap between them is a signal [E2](https://bugbountylibrary.com/r/h1%3A175091.md).

## How to review
For each runtime name lookup or stored field, ask: can user code change what this name resolves to, or supply an object of another type? The invariant: before an object is treated as type T (fields read, function pointers called), it must be proven to be T — either by a cached class reference that user code cannot rebind, or by an explicit type check at the sink. Check that constructors use cached class pointers, that raise/error paths verify the object is an exception, and that setstate validates every stored field with the matching check (e.g. iterator check) before it reaches the consumer [E1](https://bugbountylibrary.com/r/h1%3A181910.md)[E2](https://bugbountylibrary.com/r/h1%3A175091.md)[E3](https://bugbountylibrary.com/r/h1%3A185041.md).

## How finders spotted it
- Noticed one core constructor did runtime constant lookup while other core classes cached their class in interpreter state; hypothesized redefining the constant would confuse struct layout [E1](https://bugbountylibrary.com/r/h1%3A181910.md).
- Code review found a missing type check in `chain_setstate()` versus sibling setstate functions, then crafted a non-iterator argument to confirm the crash [E2](https://bugbountylibrary.com/r/h1%3A175091.md).
- Observed error macros were runtime lookups, not constants, and hypothesized exception types could be redefined; confirmed with a minimal snippet [E3](https://bugbountylibrary.com/r/h1%3A185041.md).

## Variants seen
- Redefining a core class constant (Range) so a constructor allocates the wrong struct [E1](https://bugbountylibrary.com/r/h1%3A181910.md).
- Redefining an exception class so a raise path sets a non-exception object [E3](https://bugbountylibrary.com/r/h1%3A185041.md).
- Passing a non-iterator into a setstate path that stores it unchecked [E2](https://bugbountylibrary.com/r/h1%3A175091.md).

## Impact and severity
Crashes (segfault, DEP access violation) in all three; E3 reached memory corruption enabling code execution [E1](https://bugbountylibrary.com/r/h1%3A181910.md)[E2](https://bugbountylibrary.com/r/h1%3A175091.md)[E3](https://bugbountylibrary.com/r/h1%3A185041.md). Impact rose where the sink was generic: E3's macro pattern made every raise site reachable, widening the surface beyond one call [E3](https://bugbountylibrary.com/r/h1%3A185041.md). Bounties ranged 1000–10000 (median 5500).

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A181910.md
- E2: https://bugbountylibrary.com/r/h1%3A175091.md
- E3: https://bugbountylibrary.com/r/h1%3A185041.md
