Skip to content

Commit

Permalink
[MERGE #4226 @leirocks] 17-11 Security Update
Browse files Browse the repository at this point in the history
  • Loading branch information
leirocks committed Nov 16, 2017
2 parents 7ac5506 + 1be2d26 commit fffb4e2
Show file tree
Hide file tree
Showing 54 changed files with 577 additions and 355 deletions.
2 changes: 1 addition & 1 deletion Build/NuGet/.pack-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.7.3
1.7.4
1 change: 1 addition & 0 deletions lib/Backend/Backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ enum IRDumpFlags
#include "SymTable.h"
#include "IR.h"
#include "Opnd.h"
#include "IntConstMath.h"
#include "IntOverflowDoesNotMatterRange.h"
#include "IntConstantBounds.h"
#include "ValueRelativeOffset.h"
Expand Down
28 changes: 26 additions & 2 deletions lib/Backend/BackwardPass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2047,8 +2047,8 @@ BackwardPass::ProcessBailOutInfo(IR::Instr * instr)
bool
BackwardPass::IsImplicitCallBailOutCurrentlyNeeded(IR::Instr * instr, bool mayNeedImplicitCallBailOut, bool hasLiveFields)
{
return this->globOpt->IsImplicitCallBailOutCurrentlyNeeded(
instr, nullptr, nullptr, this->currentBlock, hasLiveFields, mayNeedImplicitCallBailOut, false);
return this->globOpt->IsImplicitCallBailOutCurrentlyNeeded(instr, nullptr, nullptr, this->currentBlock, hasLiveFields, mayNeedImplicitCallBailOut, false) ||
this->NeedBailOutOnImplicitCallsForTypedArrayStore(instr);
}

void
Expand Down Expand Up @@ -2235,6 +2235,30 @@ BackwardPass::DeadStoreImplicitCallBailOut(IR::Instr * instr, bool hasLiveFields
}
}

bool
BackwardPass::NeedBailOutOnImplicitCallsForTypedArrayStore(IR::Instr* instr)
{
if ((instr->m_opcode == Js::OpCode::StElemI_A || instr->m_opcode == Js::OpCode::StElemI_A_Strict) &&
instr->GetDst()->IsIndirOpnd() &&
instr->GetDst()->AsIndirOpnd()->GetBaseOpnd()->GetValueType().IsLikelyTypedArray())
{
IR::Opnd * opnd = instr->GetSrc1();
if (opnd->IsRegOpnd())
{
return !opnd->AsRegOpnd()->GetValueType().IsPrimitive() &&
!opnd->AsRegOpnd()->m_sym->IsInt32() &&
!opnd->AsRegOpnd()->m_sym->IsFloat64() &&
!opnd->AsRegOpnd()->m_sym->IsFloatConst() &&
!opnd->AsRegOpnd()->m_sym->IsIntConst();
}
else
{
Assert(opnd->IsIntConstOpnd() || opnd->IsInt64ConstOpnd() || opnd->IsFloat32ConstOpnd() || opnd->IsFloatConstOpnd() || opnd->IsAddrOpnd());
}
}
return false;
}

void
BackwardPass::ProcessPendingPreOpBailOutInfo(IR::Instr *const currentInstr)
{
Expand Down
1 change: 1 addition & 0 deletions lib/Backend/BackwardPass.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ class BackwardPass
void DeadStoreImplicitCallBailOut(IR::Instr * instr, bool hasLiveFields);
void DeadStoreTypeCheckBailOut(IR::Instr * instr);
bool IsImplicitCallBailOutCurrentlyNeeded(IR::Instr * instr, bool mayNeedImplicitCallBailOut, bool hasLiveFields);
bool NeedBailOutOnImplicitCallsForTypedArrayStore(IR::Instr* instr);
bool TrackNoImplicitCallInlinees(IR::Instr *instr);
bool ProcessBailOnNoProfile(IR::Instr *instr, BasicBlock *block);

Expand Down
1 change: 1 addition & 0 deletions lib/Backend/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ add_library (Chakra.Backend OBJECT
InliningDecider.cpp
InliningHeuristics.cpp
IntBounds.cpp
IntConstMath.cpp
InterpreterThunkEmitter.cpp
JITThunkEmitter.cpp
JITOutput.cpp
Expand Down
2 changes: 2 additions & 0 deletions lib/Backend/Chakra.Backend.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@
<ClCompile Include="$(MSBuildThisFileDirectory)GlobOptBlockData.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)ValueInfo.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)JITThunkEmitter.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)IntConstMath.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AgenPeeps.h" />
Expand Down Expand Up @@ -259,6 +260,7 @@
<ClInclude Include="FunctionJITRuntimeInfo.h" />
<ClInclude Include="FunctionJITTimeInfo.h" />
<ClInclude Include="GlobOptBlockData.h" />
<ClInclude Include="IntConstMath.h" />
<ClInclude Include="IRBaseTypeList.h" />
<ClInclude Include="IRBuilderAsmJs.h" />
<ClInclude Include="BackendOpCodeAttrAsmJs.h" />
Expand Down
2 changes: 2 additions & 0 deletions lib/Backend/Chakra.Backend.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
<ClCompile Include="$(MSBuildThisFileDirectory)GlobOptBlockData.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)ValueInfo.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)JITThunkEmitter.cpp" />
<ClCompile Include="$(MSBuildThisFileDirectory)IntConstMath.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="AgenPeeps.h" />
Expand Down Expand Up @@ -345,6 +346,7 @@
<ClInclude Include="GlobOptBlockData.h" />
<ClInclude Include="ValueInfo.h" />
<ClInclude Include="JITThunkEmitter.h" />
<ClInclude Include="IntConstMath.h" />
</ItemGroup>
<ItemGroup>
<MASM Include="$(MSBuildThisFileDirectory)amd64\LinearScanMdA.asm">
Expand Down
4 changes: 2 additions & 2 deletions lib/Backend/CodeGenAllocators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
#include "Backend.h"

template<typename TAlloc, typename TPreReservedAlloc>
CodeGenAllocators<TAlloc, TPreReservedAlloc>::CodeGenAllocators(AllocationPolicyManager * policyManager, Js::ScriptContext * scriptContext, CustomHeap::CodePageAllocators<TAlloc, TPreReservedAlloc> * codePageAllocators, HANDLE processHandle)
CodeGenAllocators<TAlloc, TPreReservedAlloc>::CodeGenAllocators(AllocationPolicyManager * policyManager, Js::ScriptContext * scriptContext, ThreadContextInfo * threadContext, CustomHeap::CodePageAllocators<TAlloc, TPreReservedAlloc> * codePageAllocators, HANDLE processHandle)
: pageAllocator(policyManager, Js::Configuration::Global.flags, PageAllocatorType_BGJIT, 0)
, allocator(_u("NativeCode"), &pageAllocator, Js::Throw::OutOfMemory)
, emitBufferManager(&allocator, codePageAllocators, scriptContext, _u("JIT code buffer"), processHandle)
, emitBufferManager(&allocator, codePageAllocators, scriptContext, threadContext, _u("JIT code buffer"), processHandle)
#if !_M_X64_OR_ARM64 && _CONTROL_FLOW_GUARD
, canCreatePreReservedSegment(false)
#endif
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/CodeGenAllocators.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class CodeGenAllocators
bool canCreatePreReservedSegment;
#endif

CodeGenAllocators(AllocationPolicyManager * policyManager, Js::ScriptContext * scriptContext, CustomHeap::CodePageAllocators<TAlloc, TPreReservedAlloc> * codePageAllocators, HANDLE processHandle);
CodeGenAllocators(AllocationPolicyManager * policyManager, Js::ScriptContext * scriptContext, ThreadContextInfo * threadContext, CustomHeap::CodePageAllocators<TAlloc, TPreReservedAlloc> * codePageAllocators, HANDLE processHandle);
~CodeGenAllocators();

#if DBG
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/CodeGenWorkItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ void CodeGenWorkItem::OnWorkItemProcessFail(NativeCodeGenerator* codeGen)
#if DBG
this->allocation->allocation->isNotExecutableBecauseOOM = true;
#endif
codeGen->FreeNativeCodeGenAllocation(this->allocation->allocation->address, nullptr);
codeGen->FreeNativeCodeGenAllocation(this->allocation->allocation->address);
}
}

Expand Down
29 changes: 26 additions & 3 deletions lib/Backend/EmitBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
//----------------------------------------------------------------------------
template <typename TAlloc, typename TPreReservedAlloc, typename SyncObject>
EmitBufferManager<TAlloc, TPreReservedAlloc, SyncObject>::EmitBufferManager(ArenaAllocator * allocator, CustomHeap::CodePageAllocators<TAlloc, TPreReservedAlloc> * codePageAllocators,
Js::ScriptContext * scriptContext, LPCWSTR name, HANDLE processHandle) :
Js::ScriptContext * scriptContext, ThreadContextInfo * threadContext, LPCWSTR name, HANDLE processHandle) :
allocationHeap(allocator, codePageAllocators, processHandle),
allocator(allocator),
allocations(nullptr),
scriptContext(scriptContext),
threadContext(threadContext),
processHandle(processHandle)
{
#if DBG_DUMP
Expand Down Expand Up @@ -193,12 +194,14 @@ bool
EmitBufferManager<TAlloc, TPreReservedAlloc, SyncObject>::FreeAllocation(void* address)
{
AutoRealOrFakeCriticalSection<SyncObject> autoCs(&this->criticalSection);

#if _M_ARM
address = (void*)((uintptr_t)address & ~0x1); // clear the thumb bit
#endif
TEmitBufferAllocation* previous = nullptr;
TEmitBufferAllocation* allocation = allocations;
while(allocation != nullptr)
{
if (address >= allocation->allocation->address && address < (allocation->allocation->address + allocation->bytesUsed))
if (address == allocation->allocation->address)
{
if (previous == nullptr)
{
Expand All @@ -214,6 +217,26 @@ EmitBufferManager<TAlloc, TPreReservedAlloc, SyncObject>::FreeAllocation(void* a
this->scriptContext->GetThreadContext()->SubCodeSize(allocation->bytesCommitted);
}

#if defined(_CONTROL_FLOW_GUARD) && (_M_IX86 || _M_X64)
if (allocation->allocation->thunkAddress)
{
if (JITManager::GetJITManager()->IsJITServer())
{
((ServerThreadContext*)this->threadContext)->GetJITThunkEmitter()->FreeThunk(allocation->allocation->thunkAddress);
}
else
{
((ThreadContext*)this->threadContext)->GetJITThunkEmitter()->FreeThunk(allocation->allocation->thunkAddress);
}
}
else
#endif
{
if (!JITManager::GetJITManager()->IsJITServer() || CONFIG_FLAG(OOPCFGRegistration))
{
threadContext->SetValidCallTargetForCFG(address, false);
}
}
VerboseHeapTrace(_u("Freeing 0x%p, allocation: 0x%p\n"), address, allocation->allocation->address);

this->allocationHeap.Free(allocation->allocation);
Expand Down
3 changes: 2 additions & 1 deletion lib/Backend/EmitBuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class EmitBufferManager
{
typedef EmitBufferAllocation<TAlloc, TPreReservedAlloc> TEmitBufferAllocation;
public:
EmitBufferManager(ArenaAllocator * allocator, CustomHeap::CodePageAllocators<TAlloc, TPreReservedAlloc> * codePageAllocators, Js::ScriptContext * scriptContext, LPCWSTR name, HANDLE processHandle);
EmitBufferManager(ArenaAllocator * allocator, CustomHeap::CodePageAllocators<TAlloc, TPreReservedAlloc> * codePageAllocators, Js::ScriptContext * scriptContext, ThreadContextInfo * threadContext, LPCWSTR name, HANDLE processHandle);
~EmitBufferManager();

// All the following methods are guarded with the SyncObject
Expand Down Expand Up @@ -75,6 +75,7 @@ class EmitBufferManager
#endif
ArenaAllocator * allocator;
Js::ScriptContext * scriptContext;
ThreadContextInfo * threadContext;

TEmitBufferAllocation * NewAllocation(DECLSPEC_GUARD_OVERFLOW size_t bytes, ushort pdataCount, ushort xdataSize, bool canAllocInPreReservedHeapPageSegment, bool isAnyJittedCode);
TEmitBufferAllocation* GetBuffer(TEmitBufferAllocation *allocation, DECLSPEC_GUARD_OVERFLOW __in size_t bytes, __deref_bcount(bytes) BYTE** ppBuffer);
Expand Down
2 changes: 1 addition & 1 deletion lib/Backend/GlobOpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12351,7 +12351,7 @@ GlobOpt::OptConstFoldBinary(
}

IntConstType tmpValueOut;
if (!instr->BinaryCalculator(src1IntConstantValue, src2IntConstantValue, &tmpValueOut)
if (!instr->BinaryCalculator(src1IntConstantValue, src2IntConstantValue, &tmpValueOut, TyInt32)
|| !Math::FitsInDWord(tmpValueOut))
{
return false;
Expand Down
39 changes: 17 additions & 22 deletions lib/Backend/IR.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3807,28 +3807,28 @@ bool Instr::BinaryCalculatorT(T src1Const, T src2Const, int64 *pResult, bool che
template bool Instr::BinaryCalculatorT<int>(int src1Const64, int src2Const64, int64 *pResult, bool checkWouldTrap);
template bool Instr::BinaryCalculatorT<int64>(int64 src1Const64, int64 src2Const64, int64 *pResult, bool checkWouldTrap);

bool Instr::BinaryCalculator(IntConstType src1Const, IntConstType src2Const, IntConstType *pResult)
bool Instr::BinaryCalculator(IntConstType src1Const, IntConstType src2Const, IntConstType *pResult, IRType type)
{
IntConstType value = 0;

switch (this->m_opcode)
{
case Js::OpCode::Add_A:
if (IntConstMath::Add(src1Const, src2Const, &value))
if (IntConstMath::Add(src1Const, src2Const, type, &value))
{
return false;
}
break;

case Js::OpCode::Sub_A:
if (IntConstMath::Sub(src1Const, src2Const, &value))
if (IntConstMath::Sub(src1Const, src2Const, type, &value))
{
return false;
}
break;

case Js::OpCode::Mul_A:
if (IntConstMath::Mul(src1Const, src2Const, &value))
if (IntConstMath::Mul(src1Const, src2Const, type, &value))
{
return false;
}
Expand All @@ -3852,7 +3852,7 @@ bool Instr::BinaryCalculator(IntConstType src1Const, IntConstType src2Const, Int
// folds to -0. Bail for now...
return false;
}
if (IntConstMath::Div(src1Const, src2Const, &value))
if (IntConstMath::Div(src1Const, src2Const, type, &value))
{
return false;
}
Expand All @@ -3870,7 +3870,7 @@ bool Instr::BinaryCalculator(IntConstType src1Const, IntConstType src2Const, Int
// Bail for now...
return false;
}
if (IntConstMath::Mod(src1Const, src2Const, &value))
if (IntConstMath::Mod(src1Const, src2Const, type, &value))
{
return false;
}
Expand All @@ -3884,17 +3884,15 @@ bool Instr::BinaryCalculator(IntConstType src1Const, IntConstType src2Const, Int

case Js::OpCode::Shl_A:
// We don't care about overflow here
IntConstMath::Shl(src1Const, src2Const & 0x1F, &value);
value = src1Const << (src2Const & 0x1F);
break;

case Js::OpCode::Shr_A:
// We don't care about overflow here, and there shouldn't be any
IntConstMath::Shr(src1Const, src2Const & 0x1F, &value);
value = src1Const >> (src2Const & 0x1F);
break;

case Js::OpCode::ShrU_A:
// We don't care about overflow here, and there shouldn't be any
IntConstMath::ShrU(src1Const, src2Const & 0x1F, &value);
value = ((UIntConstType)src1Const) >> (src2Const & 0x1F);
if (value < 0)
{
// ShrU produces a UInt32. If it doesn't fit in an Int32, bail as we don't
Expand All @@ -3904,18 +3902,15 @@ bool Instr::BinaryCalculator(IntConstType src1Const, IntConstType src2Const, Int
break;

case Js::OpCode::And_A:
// We don't care about overflow here, and there shouldn't be any
IntConstMath::And(src1Const, src2Const, &value);
value = src1Const & src2Const;
break;

case Js::OpCode::Or_A:
// We don't care about overflow here, and there shouldn't be any
IntConstMath::Or(src1Const, src2Const, &value);
value = src1Const | src2Const;
break;

case Js::OpCode::Xor_A:
// We don't care about overflow here, and there shouldn't be any
IntConstMath::Xor(src1Const, src2Const, &value);
value = src1Const ^ src2Const;
break;

case Js::OpCode::InlineMathMin:
Expand All @@ -3935,7 +3930,7 @@ bool Instr::BinaryCalculator(IntConstType src1Const, IntConstType src2Const, Int
return true;
}

bool Instr::UnaryCalculator(IntConstType src1Const, IntConstType *pResult)
bool Instr::UnaryCalculator(IntConstType src1Const, IntConstType *pResult, IRType type)
{
IntConstType value = 0;

Expand All @@ -3948,14 +3943,14 @@ bool Instr::UnaryCalculator(IntConstType src1Const, IntConstType *pResult)
return false;
}

if (IntConstMath::Neg(src1Const, &value))
if (IntConstMath::Neg(src1Const, type, &value))
{
return false;
}
break;

case Js::OpCode::Not_A:
IntConstMath::Not(src1Const, &value);
value = ~src1Const;
break;

case Js::OpCode::Ld_A:
Expand All @@ -3973,14 +3968,14 @@ bool Instr::UnaryCalculator(IntConstType src1Const, IntConstType *pResult)
break;

case Js::OpCode::Incr_A:
if (IntConstMath::Inc(src1Const, &value))
if (IntConstMath::Inc(src1Const, type, &value))
{
return false;
}
break;

case Js::OpCode::Decr_A:
if (IntConstMath::Dec(src1Const, &value))
if (IntConstMath::Dec(src1Const, type, &value))
{
return false;
}
Expand Down
4 changes: 2 additions & 2 deletions lib/Backend/IR.h
Original file line number Diff line number Diff line change
Expand Up @@ -334,10 +334,10 @@ class Instr
bool IsCmCC_R8();
bool IsCmCC_I4();
bool IsNeq();
bool BinaryCalculator(IntConstType src1Const, IntConstType src2Const, IntConstType *pResult);
bool BinaryCalculator(IntConstType src1Const, IntConstType src2Const, IntConstType *pResult, IRType type);
template <typename T>
bool BinaryCalculatorT(T src1Const, T src2Const, int64 *pResult, bool checkWouldTrap);
bool UnaryCalculator(IntConstType src1Const, IntConstType *pResult);
bool UnaryCalculator(IntConstType src1Const, IntConstType *pResult, IRType type);
IR::Instr* GetNextArg();

// Iterates argument chain
Expand Down
Loading

0 comments on commit fffb4e2

Please sign in to comment.