# Signed index missing lower bound

Signed index or class id checked on one side only, then used to index an array or bitmap

_Area: Memory corruption and native code. Seen in 17 disclosed reports; 11 confirmed bounties, median $1,000, range $500-$10,000; latest 2024-05-09. Updated 2026-10-22._

## How it works
A value from outside the program (network message, ioctl, shared memory, image metadata) is used as an array or bitmap index. The code checks one bound, usually the upper one, and assumes the value cannot be negative. A negative signed value then indexes before the start of the array, or a large positive value is scaled/shifted and wraps to a negative offset. Either way the access lands outside the intended object, and the attacker controls what is read or written there.

## Where it shows up
- Signed int8/int32 fields parsed from messages and used directly as array indices [E1](https://bugbountylibrary.com/r/h1%3A876719.md)[E7](https://bugbountylibrary.com/r/h1%3A513154.md)
- Index checked `>= 0` but not against the array size, or checked against size but not for sign [E2](https://bugbountylibrary.com/r/h1%3A807772.md)[E4](https://bugbountylibrary.com/r/h1%3A153776.md)
- Index shifted or multiplied before the access, so overflow can flip the sign [E2](https://bugbountylibrary.com/r/h1%3A807772.md)[E5](https://bugbountylibrary.com/r/blog%3Azerodayinitiative-com-blog-2024-5-9-cve-2024-21115-an-oracle-virtualbox-lpe-used-to-win-pwn2own.md)
- Shared-memory fields written by a low-privilege process and used as indices by a privileged one [E3](https://bugbountylibrary.com/r/h1%3A520903.md)
- `set_bit`/`clear_bit` with a user-controlled bit number [E8](https://bugbountylibrary.com/r/p0%3ACVE-2023-33106.md)
- Release builds where Asserts are compiled out, leaving "validated" indices unchecked [E6](https://bugbountylibrary.com/r/blog%3Actf-re-source-engine-exploitation-2021-05-01-source-engine-2.md)

## How to review
For every array or bitmap access, find where the index comes from and confirm both bounds are enforced at the sink, not at some earlier setter. The invariant: `0 <= index < array_length` must hold immediately before the access, after any scaling or shifting, and the check must survive in release builds. For setters that store a value used later as an index, check the setter too, since a consumer's `>= 0` test does not catch a negative stored value [E4](https://bugbountylibrary.com/r/h1%3A153776.md). For shared memory, treat every field written by the less-privileged side as attacker-controlled [E3](https://bugbountylibrary.com/r/h1%3A520903.md).

## Variants seen
- Negative class id indexing a class table for an OOB write [E1](https://bugbountylibrary.com/r/h1%3A876719.md)
- Large positive entity index shifted left, wrapping to a negative offset [E2](https://bugbountylibrary.com/r/h1%3A807772.md)
- Unvalidated bucket index from worker-written scoreboard used by root [E3](https://bugbountylibrary.com/r/h1%3A520903.md)
- Negative transparent color used as alpha array index [E4](https://bugbountylibrary.com/r/h1%3A153776.md)
- Address multiplied by 4 clearing bits past a dirty-page bitmap [E5](https://bugbountylibrary.com/r/blog%3Azerodayinitiative-com-blog-2024-5-9-cve-2024-21115-an-oracle-virtualbox-lpe-used-to-win-pwn2own.md)
- Entity index underflow reaching a hijacked vtable call [E6](https://bugbountylibrary.com/r/blog%3Actf-re-source-engine-exploitation-2021-05-01-source-engine-2.md)
- Signed-char weapon id underflowing a weapon table [E7](https://bugbountylibrary.com/r/h1%3A513154.md)
- User-controlled bit index in `set_bit` [E8](https://bugbountylibrary.com/r/p0%3ACVE-2023-33106.md)

## Impact and severity
Led to client RCE from a malicious server [E1](https://bugbountylibrary.com/r/h1%3A876719.md)[E2](https://bugbountylibrary.com/r/h1%3A807772.md)[E6](https://bugbountylibrary.com/r/blog%3Actf-re-source-engine-exploitation-2021-05-01-source-engine-2.md)[E7](https://bugbountylibrary.com/r/h1%3A513154.md), local root privilege escalation [E3](https://bugbountylibrary.com/r/h1%3A520903.md), full RCE in PHP GD [E4](https://bugbountylibrary.com/r/h1%3A153776.md), LPE in VirtualBox [E5](https://bugbountylibrary.com/r/blog%3Azerodayinitiative-com-blog-2024-5-9-cve-2024-21115-an-oracle-virtualbox-lpe-used-to-win-pwn2own.md), and in-the-wild kernel exploitation [E8](https://bugbountylibrary.com/r/p0%3ACVE-2023-33106.md). Severity rises when the out-of-bounds target holds function pointers or vtables, when the index is reachable from a remote peer, and when the privileged side consumes attacker-written memory.

## Why fixes fail
Checking only one bound, or checking at the setter while the consumer trusts the value, leaves the negative case open [E4](https://bugbountylibrary.com/r/h1%3A153776.md). Asserts that vanish in release builds give no protection [E6](https://bugbountylibrary.com/r/blog%3Actf-re-source-engine-exploitation-2021-05-01-source-engine-2.md).

## Evidence
- E1: https://bugbountylibrary.com/r/h1%3A876719.md
- E2: https://bugbountylibrary.com/r/h1%3A807772.md
- E3: https://bugbountylibrary.com/r/h1%3A520903.md
- E4: https://bugbountylibrary.com/r/h1%3A153776.md
- E5: https://bugbountylibrary.com/r/blog%3Azerodayinitiative-com-blog-2024-5-9-cve-2024-21115-an-oracle-virtualbox-lpe-used-to-win-pwn2own.md
- E6: https://bugbountylibrary.com/r/blog%3Actf-re-source-engine-exploitation-2021-05-01-source-engine-2.md
- E7: https://bugbountylibrary.com/r/h1%3A513154.md
- E8: https://bugbountylibrary.com/r/p0%3ACVE-2023-33106.md
