Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

17-11 Security Update #4226

Merged
merged 18 commits into from
Nov 16, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
14f44de
[CVE-2017-11843] Edge - UAF in chakra the bug is in Js::GlobalObject:…
leirocks Oct 20, 2017
38a37ac
[CVE-2017-11837] [ChakraCore] Edge - TypedArray UaF leads to RCE - Qi…
rajatd Oct 20, 2017
b44ee83
[CVE-2017-11870] Edge - Exploitable write-AV when writing to a slot o…
rajatd Oct 20, 2017
f8098c2
[CVE-2017-11841] JIT: Inline::InlineCallApplyTarget_Shared doesn't re…
rajatd Oct 20, 2017
b54e0d6
[CVE-2017-11858] Chakra - Regular Expression Integer Overflow Leads t…
leirocks Oct 23, 2017
79edb68
[CVE-2017-11836] Edge - Assertion only bound check can lead to user c…
tcare Aug 17, 2017
a8d64f1
[CVE-2017-11873] Edge - Chakra: JIT: Bailouts must be generated for O…
Cellule Sep 25, 2017
2c9654e
[CVE-2017-11791] Fix code patterns where accessing a local Javascript…
Oct 26, 2017
874551d
[CVE-2017-11840] [ChakraCore]: JIT: GlobOpt::OptTagChecks must consid…
Nov 2, 2017
5a4e655
[CVE-2017-11874] [ChakraCore]: CFG bypass due to a bug in ServerFreeA…
MikeHolman Nov 3, 2017
c1bdfff
[CVE-2017-11838] [ChakraCore] - JIT optimization vulnerability could …
MikeHolman Nov 3, 2017
85d42e7
[CVE-2017-11861] [ChakraCore] Chakra JIT - Incorrect integer overflow…
MikeHolman Sep 18, 2017
3f8cc2d
[CVE-2017-11846] [ChakraCore]- Chakra Array.Shift Heap Overflow RCE -…
akroshg Nov 10, 2017
66d733b
[CVE-2017-11862] [ChakraCore] Type confusion in module exports - Indi…
akroshg Nov 10, 2017
9d211a4
[CVE-2017-11871] Redeferal - Invalid pointer read during native codeg…
agarwal-sandeep Sep 6, 2017
dcf8c7a
[CVE-2017-11859] Chakra - Type confusion in OOP JIT context handles -…
leirocks Nov 13, 2017
c9855d9
after fixing eval map to not be used with property string, repeatedly…
leirocks Nov 15, 2017
1be2d26
Update ChakraCore version to 1.7.4
leirocks Nov 12, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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