19.11.2016 Views

Technical Analysis of the Pegasus Exploits on iOS

eNQc3Ry

eNQc3Ry

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

objects, stored within <str<strong>on</strong>g>the</str<strong>on</strong>g> individual PropertyDescriptors in <str<strong>on</strong>g>the</str<strong>on</strong>g> descriptors vector, be individually<br />

marked to ensure that <str<strong>on</strong>g>the</str<strong>on</strong>g>se references to not become stale. To achieve this, a<br />

MarkedArgumentBuffer is used. This class is intended to temporarily prevent <str<strong>on</strong>g>the</str<strong>on</strong>g> values<br />

appended to it from being garbage collected during <str<strong>on</strong>g>the</str<strong>on</strong>g> period for which it is in scope.<br />

To understand how MarkedArgumentBuffers work we must first understand some basics <str<strong>on</strong>g>of</str<strong>on</strong>g><br />

JavaScriptCore garbage collecti<strong>on</strong>. The garbage collector is resp<strong>on</strong>sible for deallocating objects<br />

that are no l<strong>on</strong>ger referenced and runs at random intervals that increase in frequency as more<br />

memory is used by <str<strong>on</strong>g>the</str<strong>on</strong>g> WebC<strong>on</strong>tent process. To determine whe<str<strong>on</strong>g>the</str<strong>on</strong>g>r an object is referenced, <str<strong>on</strong>g>the</str<strong>on</strong>g><br />

garbage collector walks <str<strong>on</strong>g>the</str<strong>on</strong>g> stack and looks for references to <str<strong>on</strong>g>the</str<strong>on</strong>g> object. References to an<br />

object may also exist <strong>on</strong> <str<strong>on</strong>g>the</str<strong>on</strong>g> applicati<strong>on</strong> heap, however, so an alternate mechanism (which will<br />

be explained in detail below) must be used for <str<strong>on</strong>g>the</str<strong>on</strong>g>se cases.<br />

A MarkedArgumentBuffer initially attempts to maintain an inline stack buffer c<strong>on</strong>taining each<br />

value. When <str<strong>on</strong>g>the</str<strong>on</strong>g> stack is walked within garbage collecti<strong>on</strong>, each value will be noted and <str<strong>on</strong>g>the</str<strong>on</strong>g><br />

underlying objects will avoid deallocati<strong>on</strong>.<br />

class MarkedArgumentBuffer {<br />

...<br />

private:<br />

static c<strong>on</strong>st size_t inlineCapacity = 8;<br />

…<br />

public:<br />

...<br />

MarkedArgumentBuffer()<br />

: m_size(0)<br />

, m_capacity(inlineCapacity)<br />

, m_buffer(m_inlineBuffer)<br />

, m_markSet(0)<br />

{<br />

}<br />

...<br />

void append(JSValue v)<br />

{<br />

if (m_size >= m_capacity)<br />

return slowAppend(v);<br />

slotFor(m_size) = JSValue::encode(v);<br />

++m_size;<br />

}<br />

...<br />

private:<br />

...<br />

int m_size;<br />

int m_capacity;<br />

EncodedJSValue m_inlineBuffer[inlineCapacity];<br />

EncodedJSValue* m_buffer;<br />

ListSet* m_markSet;<br />

The size <str<strong>on</strong>g>of</str<strong>on</strong>g> this inline stack buffer is limited to eight values. When <str<strong>on</strong>g>the</str<strong>on</strong>g> ninth value is added to a<br />

MarkedArgumentBuffer, <str<strong>on</strong>g>the</str<strong>on</strong>g> underlying buffer is moved to <str<strong>on</strong>g>the</str<strong>on</strong>g> heap and <str<strong>on</strong>g>the</str<strong>on</strong>g> capacity is<br />

expanded.<br />

Page 4

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!