Skip to content

Commit bdd22d1

Browse files
committed
[CVE-2019-0610] Chakra JIT server EnsureLoopBodyLoadSlot out-of-bounds read&write
1 parent b778ca8 commit bdd22d1

File tree

3 files changed

+20
-7
lines changed

3 files changed

+20
-7
lines changed

lib/Backend/IRBuilder.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,8 @@ IRBuilder::Build()
774774
if (!this->RegIsTemp(dstRegSlot) && !this->RegIsConstant(dstRegSlot))
775775
{
776776
SymID symId = dstSym->m_id;
777+
778+
AssertOrFailFast(symId < m_stSlots->Length());
777779
if (this->m_stSlots->Test(symId))
778780
{
779781
// For jitted loop bodies that are in a try block, we consider any symbol that has a
@@ -4135,7 +4137,12 @@ IRBuilder::EnsureLoopBodyLoadSlot(SymID symId, bool isCatchObjectSym)
41354137
return;
41364138
}
41374139
StackSym * symDst = StackSym::FindOrCreate(symId, (Js::RegSlot)symId, m_func);
4138-
if (symDst->m_isCatchObjectSym || this->m_ldSlots->TestAndSet(symId))
4140+
if (symDst->m_isCatchObjectSym)
4141+
{
4142+
return;
4143+
}
4144+
AssertOrFailFast(symId < m_ldSlots->Length());
4145+
if (this->m_ldSlots->TestAndSet(symId))
41394146
{
41404147
return;
41414148
}
@@ -4179,6 +4186,7 @@ IRBuilder::SetLoopBodyStSlot(SymID symID, bool isCatchObjectSym)
41794186
return;
41804187
}
41814188
}
4189+
AssertOrFailFast(symID < m_stSlots->Length());
41824190
this->m_stSlots->Set(symID);
41834191
}
41844192

lib/Backend/IRBuilderAsmJs.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3570,7 +3570,10 @@ IRBuilderAsmJs::BuildAsmJsLoopBodySlotOpnd(Js::RegSlot regSlot, IRType opndType)
35703570
void
35713571
IRBuilderAsmJs::EnsureLoopBodyAsmJsLoadSlot(Js::RegSlot regSlot, IRType type)
35723572
{
3573-
if (GetJitLoopBodyData().GetLdSlots()->TestAndSet(regSlot))
3573+
BVFixed* ldSlotsBV = GetJitLoopBodyData().GetLdSlots();
3574+
3575+
AssertOrFailFast(regSlot < ldSlotsBV->Length());
3576+
if (ldSlotsBV->TestAndSet(regSlot))
35743577
{
35753578
return;
35763579
}
@@ -3592,7 +3595,6 @@ void
35923595
IRBuilderAsmJs::EnsureLoopBodyAsmJsStoreSlot(Js::RegSlot regSlot, IRType type)
35933596
{
35943597
Assert(!RegIsTemp(regSlot) || RegIsJitLoopYield(regSlot));
3595-
GetJitLoopBodyData().GetStSlots()->Set(regSlot);
35963598
EnsureLoopBodyAsmJsLoadSlot(regSlot, type);
35973599
}
35983600

lib/Backend/IRBuilderAsmJs.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ struct JitLoopBodyData
2626
{
2727
private:
2828
BVFixed* m_ldSlots = nullptr;
29-
BVFixed* m_stSlots = nullptr;
3029
StackSym* m_loopBodyRetIPSym = nullptr;
3130
BVFixed* m_yieldRegs = nullptr;
3231
uint32 m_loopCurRegs[WAsmJs::LIMIT];
@@ -36,7 +35,6 @@ struct JitLoopBodyData
3635
{
3736
Assert(ldSlots && stSlots && loopBodyRetIPSym);
3837
m_ldSlots = ldSlots;
39-
m_stSlots = stSlots;
4038
m_loopBodyRetIPSym = loopBodyRetIPSym;
4139
}
4240
// Use m_yieldRegs initialization to determine if m_loopCurRegs is initialized
@@ -57,14 +55,19 @@ struct JitLoopBodyData
5755
}
5856
bool IsYieldReg(Js::RegSlot reg) const
5957
{
60-
return m_yieldRegs && m_yieldRegs->Test(reg);
58+
if (!m_yieldRegs)
59+
{
60+
return false;
61+
}
62+
AssertOrFailFast(reg < m_yieldRegs->Length());
63+
return m_yieldRegs->Test(reg);
6164
}
6265
void SetRegIsYield(Js::RegSlot reg)
6366
{
6467
Assert(m_yieldRegs);
68+
AssertOrFailFast(reg < m_yieldRegs->Length());
6569
m_yieldRegs->Set(reg);
6670
}
67-
BVFixed* GetStSlots() const { return m_stSlots; }
6871
BVFixed* GetLdSlots() const { return m_ldSlots; }
6972
StackSym* GetLoopBodyRetIPSym() const { return m_loopBodyRetIPSym; }
7073

0 commit comments

Comments
 (0)