<div style="font-family: arial, helvetica, sans-serif; font-size: 10pt">On Wed, Nov 14, 2012 at 11:32 PM, Maciej Stachowiak <span dir="ltr">&lt;<a href="mailto:mjs@apple.com" target="_blank">mjs@apple.com</a>&gt;</span> wrote:<br>
<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div class="h5"><br><div><div>On Nov 14, 2012, at 11:09 PM, Chris Evans &lt;<a href="mailto:cevans@chromium.org" target="_blank">cevans@chromium.org</a>&gt; wrote:</div>
<br><blockquote type="cite"><div style="font-family:arial,helvetica,sans-serif;font-size:10pt">On Wed, Nov 14, 2012 at 8:59 PM, Ryosuke Niwa <span dir="ltr">&lt;<a href="mailto:rniwa@webkit.org" target="_blank">rniwa@webkit.org</a>&gt;</span> wrote:<br>

<div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>On Wed, Nov 14, 2012 at 8:52 PM, Elliott Sprehn <span dir="ltr">&lt;<a href="mailto:esprehn@chromium.org" target="_blank">esprehn@chromium.org</a>&gt;</span> wrote:<br>

</div><div class="gmail_quote"><div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div style="font-family:arial,helvetica,sans-serif;font-size:10pt"><div style="font-family:arial,helvetica,sans-serif;font-size:10pt">I was present for one of the discussions about the exploit and how an arena like allocator could have helped at Google. One proposed solution was to allocate all the JS typed buffers in an arena.<div>






<br></div><div>Is there a reason we can&#39;t just do that? It&#39;s much less intrusive to allocate ArrayBuffer in an arena than to allocate all DOM objects in one.</div></div></div></blockquote><div><br></div></div><div>

I don’t think allocating all JS objects in an arena is good enough because attackers can inject nearly arbitrary sequence of bytes into DOM objects (e.g. text node).</div></div></blockquote><div><br></div><div>Yeah, pretty much this. The worry is that it&#39;s very hard to be sure you&#39;ve identified all cases / classes where the attacker has reasonable control over the size and exact content of the allocation. You have to start looking at the buffers backing ArrayBuffers, the buffers backing WTF::Vectors, the buffers backing the (multitude of) string classes, and even then, you&#39;re left worrying about objects that simply have a bunch of consecutive ints that the attacker can set as properties, etc. And even in the unlikely event you catch everything in WebKit, you still have other very attacker-controllable allocations going on in the same process such as audio and video packets; canvas buffers; rendered image buffers; the list goes on. I don&#39;t think it&#39;s a battle than can be won.</div>

<div><br></div><div>So we think the problem is best approached from another observation:</div><div><br></div><div>- Use-after-free of certain classes is either very lethal, or very common, or both.</div><div><br></div><div>

Use-after-free is pretty common for the RenderObject hierarchy and the Node hierarchy. Inferno ran a quick script for use-after-free stats in automated ClusterFuzz reports and it was approximately 332 Render and 134 Node. Due to historical accident, we already have a protection for RenderObject.</div>

<div><br></div><div>The most lethal use-after-frees, though, are DOM objects. A freed DOM object is often wired directly into Javascript and the attacker can prod all sorts of methods and properties on the freed object in order to cause a chosen set of accesses (corresponding to reads, writes and vtable usages under the covers) in a chosen order.</div>

<div><br></div><div>I&#39;m not comfortable sharing it verbatim on a public list, but happy to send you a copy of the Pinkie Pie exploit if you&#39;re interested. It relies on a lethal DOM use-after-free.</div></div></div>
</blockquote><blockquote type="cite"><div style="font-family:arial,helvetica,sans-serif;font-size:10pt"><div class="gmail_quote"><div><br></div>
<div>Because use-after-free in the Node hierarchy is both common and lethal, a separate allocation area seems a profitable path forward.</div></div></div></blockquote><br></div></div></div><div>It still seems to me like the key difference is vtable vs no vtable,</div>
</div></blockquote><div><br></div><div>It&#39;s an important difference, but if we partitioned in to two based on that difference alone, we&#39;d have the following issues:</div><div><br></div><div>1) Classes with multiple vtables would spoil our day. The sheer number of classes in the &quot;vtable&quot; partition would practically ensure that an attacker could overlap data of their choosing on top of a secondary vtable.</div>
<div>Overlap of attacker data onto a secondary vtable is also a concern with the DOM partition approach, but the chances of it being possible are much much lower. In the Pinkie Pie exploit case, the DOM arena solution made it impossible.</div>
<div><br></div><div>2) The Pinkie Pie exploit wasn&#39;t exclusively about the vtable.</div><div>Before you can abuse an overlap with a freed vtable pointer, you need to defeat ASLR. This was partly achieved by overlapping the pointer and size of a freed WTF::Vector member with arbitrary data. (This is highly dangerous for DOM objects as it can lead to a direct arbitrary memory read or write primitive from Javascript!) Again, the sheer number of classes in a &quot;vtable&quot; partition would make a collision profitable to the attacker a statistical likelihood. Again, with a strict DOM arena, possibilities are really shut down. Back to the Pinkie Pie case, there wasn&#39;t any immediately useful overlap in either the 32-bit or 64-bit memory layout.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div>rather than DOM vs. not DOM. Also having a per-document arena for DOM nodes (as is done for render objects via RenderArena) seems irrelevant to the security goal and likely to cause bad memory fragmentation.</div>
</div></blockquote><div><br></div><div>My read on the Arena is that it&#39;s fragmentation resistant (i.e. it will not repurpose a larger free chunk to satisfy a smaller allocation.) However, memory usage at any given time is defined by peak usage since it cannot release pages back to the system without ruining its security guarantee. Interestingly, it can&#39;t be super bad: we already bite this bullet for RenderArena as used by RenderObjects. The RenderArena lifetime is the same as the document / DOM and I was surprised to recently be told that we don&#39;t throw away the RenderArena on a full layout.</div>
<div><br></div><div><br></div><div>Cheers</div><div>Chris</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><br>
</div><div>Allocating everything with a vtable separately seems like it would achieve the security goals, avoid the need to thread arena pointers everywhere, and avoid poor behavior in pathological situations, among the many flaws of RenderArenas as they exist today (see e.g. Geoff&#39;s list). Classes with a vtable method can if necessary be identified at compile/link time so we could check that they are given the right allocation behavior. That&#39;s much easier to do reliably than trying to identify buffers that are easily writable from JavaScript. And it makes more sense than segregating Node subclasses. (Note also that lots of classes that don&#39;t inherit from Node are exposed to JS too!)</div>
<div><br></div><div>Regards,</div><div>Maciej</div><div><br></div><div><br></div><br></div></blockquote></div><br></div>