# Misusing of FPU Instruction Could Cause Security Vulnerabilities in Adobe Flash Player

Flash Player JIT fails to pop FPU stack registers, so repeated calls overflow the x87 stack and a string-conversion loop writes past the stack buffer.

- Payout: hidden
- Severity: high
- Program: Internet Bug Bounty
- Found by: yopwn
- Disclosed: 2019-11-12
- CVE: CVE-2015-3100
- Write-up quality: 8/10
- Original: https://hackerone.com/reports/66962
- Library page: https://bugbountylibrary.com/r/h1%3A66962
- Tags: area:os domain:desktop impact:dos impact:rce kind:bounty platform:hackerone sev:high tech:windows technique:reverse-engineering technique:source-review vuln:memory-corruption

**Target:** Flash Player JIT-compiled ActionScript (x87 FPU / MathUtils::convertDoubleToStringRadix)
**Root cause:** JITed code calls a helper that pushes an x87 register (fild/fld) without ever popping it, so the 8-entry FPU stack fills up; subsequent FPU instructions silently fail, leaving loop conditions unevaluated.
**Steps:**
1. Craft a SWF whose method_body repeatedly invokes the JITed function at sub_9CE380 that executes `fild [esp+arg_0]` or `fld qword ptr [eax]` and returns without `fstp`.
2. Call it 6+ times so st(0)-st(5) are marked in-use, exhausting the x87 stack.
3. Trigger MathUtils::convertDoubleToStringRadix (sub_009EB440); `fld1` at 009EB4C7 fails because all 8 registers are in-use.
4. The failed FPU compare leaves the loop condition unevaluated, so the `*v4-- = v9` loop never exits and overwrites stack memory downward.
5. Observe WRITE exception at 009eb50d `mov byte ptr [esi],al` with stack filled with 0x57.
**How found:** Reading x87 FPU semantics (8-register stack, caller must pop) and disassembling the JITed helper, noticing the `fild`/`fld` with no matching pop and that the caller also never cleans registers; then tracing which downstream routine misbehaves when the stack is full.
**Exploitation:** PoC.swf drives the FPU stack to overflow, causing a failed fld1 in the double-to-string radix conversion loop; the loop never terminates and writes 0x57 bytes down the stack until an access violation. Author notes a working RCE exploit looked not quite possible from this crash alone.
**Insight:** JIT and runtime helpers that push x87 registers must pop them; a leaked FPU stack entry makes later FPU instructions fail silently, so any loop whose exit condition depends on an FPU compare can run away and corrupt memory. Audit JIT stubs for unbalanced fild/fld vs fstp.

