Skip to content

Commit

Permalink
[CVE-2017-11916] Remote Code Execution Vul - Qihoo 360
Browse files Browse the repository at this point in the history
  • Loading branch information
rajatd authored and MikeHolman committed Dec 7, 2017
1 parent d97375c commit 69e03c3
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 37 deletions.
100 changes: 63 additions & 37 deletions lib/Backend/Lower.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18425,22 +18425,28 @@ Lowerer::GenerateFastReplace(IR::Opnd* strOpnd, IR::Opnd* src1, IR::Opnd* src2,
this->GenerateStringTest(src2->AsRegOpnd(), insertInstr, labelHelper);
}

//scriptContext, pRegEx, pThis, pReplace (to be pushed in reverse order)

// pReplace, pThis, pRegEx
this->m_lowererMD.LoadHelperArgument(insertInstr, src2);
this->m_lowererMD.LoadHelperArgument(insertInstr, strOpnd);
this->m_lowererMD.LoadHelperArgument(insertInstr, src1);

// script context
LoadScriptContext(insertInstr);

IR::Instr * helperCallInstr = IR::Instr::New(LowererMD::MDCallOpcode, insertInstr->m_func);
if(callDst)
if (callDst)
{
helperCallInstr->SetDst(callDst);
}
insertInstr->InsertBefore(helperCallInstr);

if (insertInstr->HasBailOutInfo() && BailOutInfo::IsBailOutOnImplicitCalls(insertInstr->GetBailOutKind()))
{
helperCallInstr = AddBailoutToHelperCallInstr(helperCallInstr, insertInstr->GetBailOutInfo(), insertInstr->GetBailOutKind(), insertInstr);
}

//scriptContext, pRegEx, pThis, pReplace (to be pushed in reverse order)

// pReplace, pThis, pRegEx
this->m_lowererMD.LoadHelperArgument(helperCallInstr, src2);
this->m_lowererMD.LoadHelperArgument(helperCallInstr, strOpnd);
this->m_lowererMD.LoadHelperArgument(helperCallInstr, src1);

// script context
LoadScriptContext(helperCallInstr);

if(callDst)
{
m_lowererMD.ChangeToHelperCall(helperCallInstr, IR::JnHelperMethod::HelperRegExp_ReplaceStringResultUsed);
Expand Down Expand Up @@ -18520,22 +18526,33 @@ Lowerer::GenerateFastInlineStringSplitMatch(IR::Instr * instr)
labelHelper,
instr);

IR::Instr * helperCallInstr = IR::Instr::New(LowererMD::MDCallOpcode, instr->m_func);
if (callDst)
{
helperCallInstr->SetDst(callDst);
}
instr->InsertBefore(helperCallInstr);
if (instr->HasBailOutInfo() && BailOutInfo::IsBailOutOnImplicitCalls(instr->GetBailOutKind()))
{
helperCallInstr = AddBailoutToHelperCallInstr(helperCallInstr, instr->GetBailOutInfo(), instr->GetBailOutKind(), instr);
}

// [stackAllocationPointer, ]scriptcontext, regexp, input[, limit] (to be pushed in reverse order)

if(src1->AsHelperCallOpnd()->m_fnHelper == IR::JnHelperMethod::HelperString_Split)
{
//limit
//As we are optimizing only for two operands, make limit UINT_MAX
IR::Opnd* limit = IR::IntConstOpnd::New(UINT_MAX, TyUint32, instr->m_func);
this->m_lowererMD.LoadHelperArgument(instr, limit);
this->m_lowererMD.LoadHelperArgument(helperCallInstr, limit);
}

//input, regexp
this->m_lowererMD.LoadHelperArgument(instr, argsOpnd[0]);
this->m_lowererMD.LoadHelperArgument(instr, argsOpnd[1]);
this->m_lowererMD.LoadHelperArgument(helperCallInstr, argsOpnd[0]);
this->m_lowererMD.LoadHelperArgument(helperCallInstr, argsOpnd[1]);

// script context
LoadScriptContext(instr);
LoadScriptContext(helperCallInstr);

IR::JnHelperMethod helperMethod = IR::JnHelperMethod::HelperInvalid;
IR::AutoReuseOpnd autoReuseStackAllocationOpnd;
Expand All @@ -18560,8 +18577,8 @@ Lowerer::GenerateFastInlineStringSplitMatch(IR::Instr * instr)
IR::RegOpnd *const stackAllocationOpnd = IR::RegOpnd::New(TyVar, m_func);
autoReuseStackAllocationOpnd.Initialize(stackAllocationOpnd, m_func);
stackAllocationOpnd->SetValueType(callDst->GetValueType());
GenerateMarkTempAlloc(stackAllocationOpnd, Js::JavascriptArray::StackAllocationSize, instr);
m_lowererMD.LoadHelperArgument(instr, stackAllocationOpnd);
GenerateMarkTempAlloc(stackAllocationOpnd, Js::JavascriptArray::StackAllocationSize, helperCallInstr);
m_lowererMD.LoadHelperArgument(helperCallInstr, stackAllocationOpnd);
}
else
{
Expand All @@ -18587,13 +18604,6 @@ Lowerer::GenerateFastInlineStringSplitMatch(IR::Instr * instr)
}
}

IR::Instr * helperCallInstr = IR::Instr::New(LowererMD::MDCallOpcode, instr->m_func);
if(callDst)
{
helperCallInstr->SetDst(callDst);
}
instr->InsertBefore(helperCallInstr);

m_lowererMD.ChangeToHelperCall(helperCallInstr, helperMethod);

IR::LabelInstr *doneLabel = IR::LabelInstr::New(Js::OpCode::Label, this->m_func);
Expand Down Expand Up @@ -18768,29 +18778,39 @@ Lowerer::GenerateFastInlineRegExpExec(IR::Instr * instr)
instr->InsertBefore(labelFastHelper);
}

IR::Instr * helperCallInstr = IR::Instr::New(LowererMD::MDCallOpcode, instr->m_func);
if (callDst)
{
helperCallInstr->SetDst(callDst);
}
instr->InsertBefore(helperCallInstr);
if (instr->HasBailOutInfo() && BailOutInfo::IsBailOutOnImplicitCalls(instr->GetBailOutKind()))
{
helperCallInstr = AddBailoutToHelperCallInstr(helperCallInstr, instr->GetBailOutInfo(), instr->GetBailOutKind(), instr);
}
// [stackAllocationPointer, ]scriptcontext, regexp, string (to be pushed in reverse order)

//string, regexp
this->m_lowererMD.LoadHelperArgument(instr, opndString);
this->m_lowererMD.LoadHelperArgument(instr, opndRegex);
this->m_lowererMD.LoadHelperArgument(helperCallInstr, opndString);
this->m_lowererMD.LoadHelperArgument(helperCallInstr, opndRegex);

// script context
LoadScriptContext(instr);
LoadScriptContext(helperCallInstr);

IR::JnHelperMethod helperMethod;
IR::AutoReuseOpnd autoReuseStackAllocationOpnd;
if(callDst)
if (callDst)
{
if(instr->dstIsTempObject)
if (instr->dstIsTempObject)
{
helperMethod = IR::JnHelperMethod::HelperRegExp_ExecResultUsedAndMayBeTemp;

// Allocate some space on the stack for the result array
IR::RegOpnd *const stackAllocationOpnd = IR::RegOpnd::New(TyVar, m_func);
autoReuseStackAllocationOpnd.Initialize(stackAllocationOpnd, m_func);
stackAllocationOpnd->SetValueType(callDst->GetValueType());
GenerateMarkTempAlloc(stackAllocationOpnd, Js::JavascriptArray::StackAllocationSize, instr);
m_lowererMD.LoadHelperArgument(instr, stackAllocationOpnd);
GenerateMarkTempAlloc(stackAllocationOpnd, Js::JavascriptArray::StackAllocationSize, helperCallInstr);
m_lowererMD.LoadHelperArgument(helperCallInstr, stackAllocationOpnd);
}
else
{
Expand All @@ -18802,12 +18822,6 @@ Lowerer::GenerateFastInlineRegExpExec(IR::Instr * instr)
helperMethod = IR::JnHelperMethod::HelperRegExp_ExecResultNotUsed;
}

IR::Instr * helperCallInstr = IR::Instr::New(LowererMD::MDCallOpcode, instr->m_func);
if(callDst)
{
helperCallInstr->SetDst(callDst);
}
instr->InsertBefore(helperCallInstr);
m_lowererMD.ChangeToHelperCall(helperCallInstr, helperMethod);

instr->InsertAfter(doneLabel);
Expand Down Expand Up @@ -25536,6 +25550,18 @@ Lowerer::InsertLoopTopLabel(IR::Instr * insertBeforeInstr)
return loopTopLabel;
}

IR::Instr *
Lowerer::AddBailoutToHelperCallInstr(IR::Instr * helperCallInstr, BailOutInfo * bailoutInfo, IR::BailOutKind bailoutKind, IR::Instr * primaryBailoutInstr)
{
helperCallInstr = helperCallInstr->ConvertToBailOutInstr(bailoutInfo, bailoutKind);
if (bailoutInfo->bailOutInstr == primaryBailoutInstr)
{
IR::Instr * instrShare = primaryBailoutInstr->ShareBailOut();
LowerBailTarget(instrShare);
}
return helperCallInstr;
}

#if DBG
void
Lowerer::LegalizeVerifyRange(IR::Instr * instrStart, IR::Instr * instrLast)
Expand Down
1 change: 1 addition & 0 deletions lib/Backend/Lower.h
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,7 @@ class Lowerer
void GenerateHasObjectArrayCheck(IR::RegOpnd * objectOpnd, IR::RegOpnd * typeOpnd, IR::LabelInstr * hasObjectArray, IR::Instr * insertBeforeInstr);

IR::LabelInstr* InsertLoopTopLabel(IR::Instr * insertBeforeInstr);
IR::Instr * AddBailoutToHelperCallInstr(IR::Instr * helperCallInstr, BailOutInfo * bailoutInfo, IR::BailOutKind bailoutKind, IR::Instr * primaryBailoutInstr);
public:
static IRType GetImplicitCallFlagsType()
{
Expand Down

0 comments on commit 69e03c3

Please sign in to comment.