|
|
Adobe Flash incorrect jit optimization with op_pushwith | ||||
| Project Member Reported by ianbeer@google.com, Sep 21 2014 | Back to list | ||||
The avmplus bytecode verifier misses a control-flow path via op_pushwith throwing an exception allowing crafted bytecode to be incorrectly optimized which can trivially be abused to get code execution. The avm2 spec [ http://www.adobe.com/content/dam/Adobe/en/devnet/actionscript/articles/avm2overview.pdf ] actually notes that pushwith can throw an exception: (p.97:) ... Runtime exceptions A TypeError is thrown if scope_obj is null or undefined ... This isn't reflected in opcodes.tbl however meaning that the verifier won't add a control flow edge between a pushwith and any catch blocks associated with enclosing try blocks: // opCount throw stack internal name hex ABC_OP( 0, 0, -1, 0, pushwith) // 0x1C Looking at the implementation of the verifier and codegen for pushwith: Verifier.cpp: ... case OP_pushwith: { checkStack(1,0); if (state->scopeDepth + 1 > ms->max_scope()) verifyFailed(kScopeStackOverflowError); emitCheckNull(sp); <-- this can throw coder->writeOp1(state, pc, opcode, ms->scope_base() + state->scopeDepth); Traits* scopeTraits = state->peek().traits; state->pop(); state->setType(ms->scope_base() + state->scopeDepth, scopeTraits, true, true); if (state->withBase == -1) state->withBase = state->scopeDepth; state->scopeDepth++; break; ... the emitCheckNull will emit code which throws a catchable exception if the scope object passed on the stack is NULL. This is exactly what the attached PoC does; it uses the same technique as the previous PoC to use this to confuse the jit engine into emitting incorrectly optimized code. Tested against the latest version of flash projector (15.0.0.152) on OS X
Project Member
Comment 1
by
ianbeer@google.com,
Sep 22 2014
,
Sep 23 2014
,
Nov 8 2014
,
Nov 20 2014
http://helpx.adobe.com/security/products/flash-player/apsb14-24.html
,
Mar 16 2016
Attaching my old exploit for this bug |
|||||
| ► Sign in to add a comment | |||||