有两个漏洞,每个漏洞都会触发跳转到地址零:
第一个,里面markContainingBlocksForLayout
:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb09fdb70 (LWP 2039)]
> 0x00000000 in ?? ()
(gdb) bt
> #0 0x00000000 in ?? ()
#1 0x0194b82b in markContainingBlocksForLayout (this=0x2e29944, owner=
0x2e298e4, oldChild=0x0, fullRemove=true)
at third_party/WebKit/WebCore/rendering/RenderObject.h:946
这是故障 eip 的程序集转储:
0x0194b81b <removeChildNode(...)+1083>: decl -0x74ffd98c(%ebp)
0x0194b821 <removeChildNode(...)+1089>: push %es
0x0194b822 <removeChildNode(...)+1090>: mov %esi,(%esp)
0x0194b825 <removeChildNode(...)+1093>: call *0xb0(%eax)
=> 0x0194b82b <removeChildNode(...)+1099>: test %al,%al
0x0194b82d <removeChildNode(...)+1101>: jne 0x194b67d <removeChildNode(...)+669>
0x0194b833 <removeChildNode(...)+1107>: mov -0x24(%ebp),%edi
0x0194b836 <removeChildNode(...)+1110>: mov -0x28(%ebp),%esi
0x0194b839 <removeChildNode(...)+1113>: jmp 0x194b728 <removeChildNode(...)+840>
该call
指令调用地址 at eax + 0xb0
,这意味着它0x02e294f8
为零(因为 eax 是0x02e29448
)。
这是第二个,里面RenderObject::destroy
:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb1646b70 (LWP 2100)]
> 0x00000000 in ?? ()
(gdb) bt
> #0 0x00000000 in ?? ()
#1 0x0194387f in WebCore::RenderObject::destroy (this=0x2e29cc4)
at third_party/WebKit/WebCore/rendering/RenderObject.cpp:2152
再次在 eip 进行反汇编:
0x0194386f <WebCore::RenderObject::destroy()+15>: xchg %eax,%ebx
0x01943870 <WebCore::RenderObject::destroy()+16>: incb 0x3dd4a3c3(%ecx)
0x01943876 <WebCore::RenderObject::destroy()+22>: add %ecx,0x24348906(%ebx)
0x0194387c <WebCore::RenderObject::destroy()+28>: call *0x24(%eax)
=> 0x0194387f <WebCore::RenderObject::destroy()+31>: test %eax,%eax
0x01943881 <WebCore::RenderObject::destroy()+33>: je 0x194388b <WebCore::RenderObject::destroy()+43>
0x01943883 <WebCore::RenderObject::destroy()+35>: mov %eax,(%esp)
0x01943886 <WebCore::RenderObject::destroy()+38>: call 0x194a680 <WebCore::RenderObjectChildList::destroyLeftoverChildren()>
0x0194388b <WebCore::RenderObject::destroy()+43>: mov 0x8(%esi),%eax
0x0194388e <WebCore::RenderObject::destroy()+46>: mov 0x14(%eax),%eax
这一次,它eax + 0x24
和 eax0x02e29d38
给了我们0x02e29d5c
. 这意味着内存0x02e29d5c
也为零。
0x02e294f8
从to的距离0x02e29d38
(小于 2KB)意味着这里有两个单独的分配被访问,所以它们几乎肯定是两个不同的错误。
修复的补丁差异表明这是一个释放后使用问题,其中对象在被删除的同时被“合并”。这可能容易受到竞争条件的影响,在这种情况下,内存被释放,然后以概率方式重新分配到其他地方,然后被这个错误跳转到,但如果不真正深入研究它,我无法判断。
您可以通过在 JavaScript 中的循环中执行大量内存分配来测试可利用性(字符串操作是一个很好的方法),然后在循环期间导致错误。如果内存被覆盖,则 use-after-free 可能会尝试跳转到您的某些字符串值。