Skip to content

Commit

Permalink
Chakra Assert : sym->HasScopeSlot()
Browse files Browse the repository at this point in the history
CVE-2016-3202

A let/const bug exposes a bad array indexing operation during bytecode
emit.  A symbol can fail to get a location due to this bug but then the
location is used to offset into an array assuming it is always valid.
Fix the array offset issue by performing a bounds check and throwing
FatalInternalError if an out of bounds access would occur.
  • Loading branch information
Ian Halliday authored and agarwal-sandeep committed Jun 17, 2016
1 parent 3b9dc1a commit ff9067e
Showing 1 changed file with 16 additions and 6 deletions.
22 changes: 16 additions & 6 deletions lib/Runtime/ByteCode/ByteCodeEmitter.cpp
Expand Up @@ -1799,37 +1799,47 @@ void ByteCodeGenerator::InitScopeSlotArray(FuncInfo * funcInfo)
propertyIdsForScopeSlotArray[i] = Js::Constants::NoProperty;
}
#endif
auto setPropertyIdForScopeSlotArray =
[scopeSlotCount, propertyIdsForScopeSlotArray]
(Js::PropertyId slot, Js::PropertyId propId)
{
if (slot < 0 || (uint)slot >= scopeSlotCount)
{
Js::Throw::FatalInternalError();
}
propertyIdsForScopeSlotArray[slot] = propId;
};

auto setPropIdsForScopeSlotArray = [funcInfo, propertyIdsForScopeSlotArray](Symbol *const sym)
auto setPropIdsForScopeSlotArray = [funcInfo, setPropertyIdForScopeSlotArray](Symbol *const sym)
{
if (sym->NeedsSlotAlloc(funcInfo))
{
// All properties should get correct propertyId here.
Assert(sym->HasScopeSlot()); // We can't allocate scope slot now. Any symbol needing scope slot must have allocated it before this point.
propertyIdsForScopeSlotArray[sym->GetScopeSlot()] = sym->EnsurePosition(funcInfo);
setPropertyIdForScopeSlotArray(sym->GetScopeSlot(), sym->EnsurePosition(funcInfo));
}
};

funcInfo->GetBodyScope()->ForEachSymbol(setPropIdsForScopeSlotArray);

if (funcInfo->thisScopeSlot != Js::Constants::NoRegister)
{
propertyIdsForScopeSlotArray[funcInfo->thisScopeSlot] = Js::PropertyIds::_lexicalThisSlotSymbol;
setPropertyIdForScopeSlotArray(funcInfo->thisScopeSlot, Js::PropertyIds::_lexicalThisSlotSymbol);
}

if (funcInfo->newTargetScopeSlot != Js::Constants::NoRegister)
{
propertyIdsForScopeSlotArray[funcInfo->newTargetScopeSlot] = Js::PropertyIds::_lexicalNewTargetSymbol;
setPropertyIdForScopeSlotArray(funcInfo->newTargetScopeSlot, Js::PropertyIds::_lexicalNewTargetSymbol);
}

if (funcInfo->superScopeSlot != Js::Constants::NoRegister)
{
propertyIdsForScopeSlotArray[funcInfo->superScopeSlot] = Js::PropertyIds::_superReferenceSymbol;
setPropertyIdForScopeSlotArray(funcInfo->superScopeSlot, Js::PropertyIds::_superReferenceSymbol);
}

if (funcInfo->superCtorScopeSlot != Js::Constants::NoRegister)
{
propertyIdsForScopeSlotArray[funcInfo->superCtorScopeSlot] = Js::PropertyIds::_superCtorReferenceSymbol;
setPropertyIdForScopeSlotArray(funcInfo->superCtorScopeSlot, Js::PropertyIds::_superCtorReferenceSymbol);
}

#if DEBUG
Expand Down

0 comments on commit ff9067e

Please sign in to comment.