Skip to content

Commit 329d9d2

Browse files
akroshgwyrichte
authored andcommitted
[CVE-2019-1141] Chakra JIT Type Confusion
During the loop prepass the index variable is not fully constructed, so we can't rely it being negative So we need to kiil the object type.
1 parent 12c31f0 commit 329d9d2

File tree

3 files changed

+12
-5
lines changed

3 files changed

+12
-5
lines changed

lib/Backend/GlobOpt.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2695,7 +2695,7 @@ GlobOpt::OptInstr(IR::Instr *&instr, bool* isInstrRemoved)
26952695
}
26962696

26972697
bool
2698-
GlobOpt::IsNonNumericRegOpnd(IR::RegOpnd *opnd, bool inGlobOpt) const
2698+
GlobOpt::IsNonNumericRegOpnd(IR::RegOpnd *opnd, bool inGlobOpt, bool *isSafeToTransferInPrepass /*=nullptr*/) const
26992699
{
27002700
if (opnd == nullptr)
27012701
{
@@ -2725,12 +2725,18 @@ GlobOpt::IsNonNumericRegOpnd(IR::RegOpnd *opnd, bool inGlobOpt) const
27252725
{
27262726
return true;
27272727
}
2728+
2729+
bool isSafeToTransfer = this->IsSafeToTransferInPrepass(opnd->m_sym, opndValueInfo);
2730+
if (isSafeToTransferInPrepass != nullptr)
2731+
{
2732+
*isSafeToTransferInPrepass = isSafeToTransfer;
2733+
}
27282734
if (this->prePassLoop->preservesNumberValue->Test(opnd->m_sym->m_id))
27292735
{
27302736
return false;
27312737
}
27322738

2733-
return !this->IsSafeToTransferInPrepass(opnd->m_sym, opndValueInfo);
2739+
return !isSafeToTransfer;
27342740
}
27352741

27362742
return true;

lib/Backend/GlobOpt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,7 +773,7 @@ class GlobOpt
773773
const bool lossy = false, const bool forceInvariantHoisting = false, IR::BailOutKind bailoutKind = IR::BailOutInvalid);
774774
void HoistInvariantValueInfo(ValueInfo *const invariantValueInfoToHoist, Value *const valueToUpdate, BasicBlock *const targetBlock);
775775
void OptHoistUpdateValueType(Loop* loop, IR::Instr* instr, IR::Opnd** srcOpndPtr, Value *const srcVal);
776-
bool IsNonNumericRegOpnd(IR::RegOpnd *opnd, bool inGlobOpt) const;
776+
bool IsNonNumericRegOpnd(IR::RegOpnd *opnd, bool inGlobOpt, bool *isSafeToTransferInPrepass = nullptr) const;
777777

778778
public:
779779
static bool IsTypeSpecPhaseOff(Func const * func);

lib/Backend/GlobOptFields.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,8 @@ GlobOpt::KillLiveElems(IR::IndirOpnd * indirOpnd, IR::Opnd * valueOpnd, BVSparse
225225
// - We check the type specialization status for the sym as well. For the purpose of doing kills, we can assume that
226226
// if type specialization happened, that fields don't need to be killed. Note that they may be killed in the next
227227
// pass based on the value.
228-
if (func->GetThisOrParentInlinerHasArguments() || this->IsNonNumericRegOpnd(indexOpnd, inGlobOpt))
228+
bool isSafeToTransfer = true;
229+
if (func->GetThisOrParentInlinerHasArguments() || this->IsNonNumericRegOpnd(indexOpnd, inGlobOpt, &isSafeToTransfer))
229230
{
230231
this->KillAllFields(bv); // This also kills all property type values, as the same bit-vector tracks those stack syms
231232
SetAnyPropertyMayBeWrittenTo();
@@ -236,7 +237,7 @@ GlobOpt::KillLiveElems(IR::IndirOpnd * indirOpnd, IR::Opnd * valueOpnd, BVSparse
236237
ValueInfo * indexValueInfo = indexValue ? indexValue->GetValueInfo() : nullptr;
237238
int indexLowerBound = 0;
238239

239-
if (indirOpnd->GetOffset() < 0 || (indexOpnd && (!indexValueInfo || !indexValueInfo->TryGetIntConstantLowerBound(&indexLowerBound, false) || indexLowerBound < 0)))
240+
if (!isSafeToTransfer || indirOpnd->GetOffset() < 0 || (indexOpnd && (!indexValueInfo || !indexValueInfo->TryGetIntConstantLowerBound(&indexLowerBound, false) || indexLowerBound < 0)))
240241
{
241242
// Write/delete to a non-integer numeric index can't alias a name on the RHS of a dot, but it change object layout
242243
this->KillAllObjectTypes(bv);

0 commit comments

Comments
 (0)