Skip to content

Commit d08f260

Browse files
committed
[1.6>1.7] [MERGE #3509 @pleath] 17-08 ChakraCore servicing release
Merge pull request #3509 from pleath:1708 Addresses the following: CVE-2017-0228 CVE-2017-8634 CVE-2017-8635 CVE-2017-8636 CVE-2017-8637 CVE-2017-8638 CVE-2017-8640 CVE-2017-8641 CVE-2017-8645 CVE-2017-8646 CVE-2017-8647 CVE-2017-8655 CVE-2017-8656 CVE-2017-8657 CVE-2017-8658 CVE-2017-8659 CVE-2017-8670 CVE-2017-8671 CVE-2017-8672 CVE-2017-8674 Details: [CVE-2017-8656] PreVisitCatch doesn't call SetIsCatch for all cases The catch block has a var declaration with the same name as the destructured parameter. When we emit code for initializing vars we don't emit the initialization code for the symbol in the body as the catch param is not marked. The fix is to mark the destructured param as catch param. Blind constants more aggressively in jitted code Let RPC do handle marshalling for the JIT process [CVE-2017-8647] Fix oop jit diff to check msvcrt instead of ucrt [CVE-2017-8637] [CVE-2017-8659] Harden JIT process against bad input [CVE-2017-8655] Prevent restoring inlinee frame with the wrong function object Invalidate lastUsedSegment of an array at the right point [CVE-2017-8638] Fix function object inline cache if function body got reparsed [CVE-2017-8657] Postpone adding deferred top-level functions to the deferred function dictionary. Do this so that if byte code gen is interrupted or restarted, we are not left with orphaned functions in the dictionary that may be semi-initialized. [CVE-2017-8658] Don't attempt to use deferred function stubs inside a formal argument list, as this leads to issues with arrow functions, nested functions, etc. [CVE-2017-8635] Don't try to reuse property indexes on re-add of a deleted property if the object is non-extensible. Doing so exhausts the free indexes on repeated re-adds, which violates our assumption that a free index will always be available if a property has been deleted. [CVE-2017-8671] Consider CallFlags_ExtraArg in Function.call implementation. Extra arg (for proxy, etc.) should not be a factor when copying/eliding arguments to delegate to the real target. [CVE-2017-8674] Re-map function object types if AutoRestoreFunctionInfo has to restore FunctionInfo on failed re-parse/byte code gen. [CVE-2017-8640] Mark the correct function node when we're detecting 'arguments' declaration that overrides the built-in declaration. [CVE-2017-8670] Make sure we mark the correct function node when we're processing formal named 'arguments' in a destructured expression. [CVE-2017-8672] Avoid passing JsNull as JsFunction* In JavascriptStackWalker GetCaller we were sending out JsNull as a JavascriptFunction* in the outparam. I checked all locations that did a call to this function, and recursively as far as the outparam escaped. Virtually all of the callers of the function or the other functions that allowed escape of the outparam were safe, as checks against the return value of GetCaller are near-ubiquitous. The one callsite where this wasn't the case was in GlobalObject.cpp L#693, which is in VEval. This location used the outparam without checks, which meant that if a JsNull object were returned, we'd call other functions which wouldn't necessarily be correct. [CVE-2017-8645] Whitelist the type of functions allow to be asm.js module [CVE-2017-8646] Correctly use PushPopFrameHelper in ProcessLinkFailedAsmJsModule. No longer ignore arbitrary javascript code after a `let` [CVE-2017-8641] Integer overflow in chakra!Js::GlobalObject Integer overflow can happen in multiple cases of add-mult and allocate. Fix by using UInt32Math::AddMul() to catch overflows. [CVE-2017-8634] Type confusion in Concat due to IsConcatSpreadable [CVE-2017-8636] Limiting args count to a certain limit. This limit will be enforced during the parser time. During the bytecode time we add so many extra args which actually overflowed the initial assumption. [CVE-2017-0228] We have attempted to fix the ReverseHelper case where the inline segment was swapped from head to bottom due to reverse loop below. However that fix was done for multi-segment scenario. The EnsureHeadStartsFromZero can also insert head segment in between if the segment's length is less than Array's length (look at the loop above), which will make the code vulnerable. Fixed that scenario by allocating the segment (for the single segment case) if the segment's length is less than array's length.
2 parents f2b5bb2 + 63034a0 commit d08f260

File tree

78 files changed

+1375
-334
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+1375
-334
lines changed

Build/Chakra.Build.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<PropertyGroup>
55
<Win32_WinNTVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_Win7)'">0x0601</Win32_WinNTVersion>
66
<Win32_WinNTVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_Win8)'">0x0602</Win32_WinNTVersion>
7+
<Win32_WinNTVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_WinBlue)'">0x0603</Win32_WinNTVersion>
78
<Win32_WinNTVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_Win10)'">0x0A00</Win32_WinNTVersion>
89

910
<!-- Always use Platform SDK for core builds -->

Build/Common.Build.Default.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<PropertyGroup>
55
<NtTargetVersion_Win7 >0x601</NtTargetVersion_Win7>
66
<NtTargetVersion_Win8 >0x602</NtTargetVersion_Win8>
7+
<NtTargetVersion_WinBlue>0x603</NtTargetVersion_WinBlue>
78
<NtTargetVersion_Win10>0xA00</NtTargetVersion_Win10>
89
</PropertyGroup>
910

Build/Common.Build.props

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
<!-- ======== sources.inc ======== -->
3030
<!-- generates SAL annotations for our interface -->
3131
<AdditionalOptions>%(AdditionalOptions) -sal_local</AdditionalOptions>
32+
33+
<PreprocessorDefinitions>%(PreprocessorDefinitions);WINVER=$(Win32_WinNTVersion)</PreprocessorDefinitions>
3234
</Midl>
3335
<ClCompile>
3436
<PreprocessorDefinitions>%(PreprocessorDefinitions);NOMINMAX;USE_EDGEMODE_JSRT</PreprocessorDefinitions>
@@ -105,6 +107,7 @@
105107

106108
<MinimumRequiredVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_Win7)'" >6.1</MinimumRequiredVersion>
107109
<MinimumRequiredVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_Win8)'" >6.2</MinimumRequiredVersion>
110+
<MinimumRequiredVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_WinBlue)'" >6.3</MinimumRequiredVersion>
108111
<MinimumRequiredVersion Condition="'$(NtTargetVersion)'=='$(NtTargetVersion_Win10)'" >10.00</MinimumRequiredVersion>
109112

110113
<!-- Always set the checksum -->

lib/Backend/AsmJsJITInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ AsmJsJITInfo::GetArgTypeArray() const
6060
Js::AsmJsVarType::Which
6161
AsmJsJITInfo::GetArgType(Js::ArgSlot argNum) const
6262
{
63-
Assert(argNum < GetArgCount());
63+
AssertOrFailFast(argNum < GetArgCount());
6464
return GetArgTypeArray()[argNum];
6565
}
6666

lib/Backend/AsmJsJITInfo.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ class AsmJsJITInfo
2828
Js::ArgSlot GetArgCount() const;
2929
Js::ArgSlot GetArgByteSize() const;
3030
Js::AsmJsRetType::Which GetRetType() const;
31-
Js::AsmJsVarType::Which * GetArgTypeArray() const;
3231
Js::AsmJsVarType::Which GetArgType(Js::ArgSlot argNum) const;
3332

3433
#ifdef ENABLE_WASM
@@ -40,6 +39,7 @@ class AsmJsJITInfo
4039
bool AccessNeedsBoundCheck(uint offset) const;
4140

4241
private:
42+
Js::AsmJsVarType::Which * GetArgTypeArray() const;
4343
AsmJsDataIDL m_data;
4444
#endif
4545
};

lib/Backend/CodeGenWorkItem.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,13 @@ struct CodeGenWorkItem : public JsUtil::Job
5858
return functionBody->GetScriptContext();
5959
}
6060

61+
uint GetByteCodeLength() const
62+
{
63+
return this->functionBody->IsInDebugMode()
64+
? this->functionBody->GetOriginalByteCode()->GetLength()
65+
: this->functionBody->GetByteCode()->GetLength();
66+
}
67+
6168
Js::FunctionBody* GetFunctionBody() const
6269
{
6370
return functionBody;

lib/Backend/Func.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,14 @@ Func::Func(JitArenaAllocator *alloc, JITTimeWorkItem * workItem,
153153

154154
Assert(this->IsInlined() == !!runtimeInfo);
155155

156+
AssertOrFailFast(!HasProfileInfo() || GetReadOnlyProfileInfo()->GetLoopCount() == GetJITFunctionBody()->GetLoopCount());
157+
Js::RegSlot tmpResult;
158+
AssertOrFailFast(!UInt32Math::Add(GetJITFunctionBody()->GetConstCount(), GetJITFunctionBody()->GetVarCount(), &tmpResult));
159+
AssertOrFailFast(GetJITFunctionBody()->IsAsmJsMode() || GetJITFunctionBody()->GetFirstTmpReg() <= GetJITFunctionBody()->GetLocalsCount());
160+
AssertOrFailFast(!IsLoopBody() || m_workItem->GetLoopNumber() < GetJITFunctionBody()->GetLoopCount());
161+
AssertOrFailFast(CONFIG_FLAG(Prejit) || CONFIG_ISENABLED(Js::ForceNativeFlag) || GetJITFunctionBody()->GetByteCodeLength() < (uint)CONFIG_FLAG(MaxJITFunctionBytecodeByteLength));
162+
GetJITFunctionBody()->EnsureConsistentConstCount();
163+
156164
if (this->IsTopFunc())
157165
{
158166
outputData->hasJittedStackClosure = false;

lib/Backend/IR.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,12 @@ Instr::HasEquivalentTypeCheckBailOut() const
8484
return this->HasBailOutInfo() && IR::IsEquivalentTypeCheckBailOutKind(this->GetBailOutKind());
8585
}
8686

87+
bool
88+
Instr::HasBailOnNoProfile() const
89+
{
90+
return this->HasBailOutInfo() && this->GetBailOutKind() == IR::BailOutOnNoProfile;
91+
}
92+
8793
void
8894
Instr::ChangeEquivalentToMonoTypeCheckBailOut()
8995
{

lib/Backend/IR.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ class Instr
203203
bool HasAuxBailOut() const { return hasAuxBailOut; }
204204
bool HasTypeCheckBailOut() const;
205205
bool HasEquivalentTypeCheckBailOut() const;
206+
bool HasBailOnNoProfile() const;
206207
void ClearBailOutInfo();
207208
bool IsDstNotAlwaysConvertedToInt32() const;
208209
bool IsDstNotAlwaysConvertedToNumber() const;

lib/Backend/IRBuilder.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ IRBuilder::Build()
400400
Js::RegSlot tempCount = m_func->GetJITFunctionBody()->GetTempCount();
401401
if (tempCount > 0)
402402
{
403-
this->tempMap = (SymID*)m_tempAlloc->AllocZero(sizeof(SymID) * tempCount);
403+
this->tempMap = AnewArrayZ(m_tempAlloc, SymID, tempCount);
404404
this->fbvTempUsed = BVFixed::New<JitArenaAllocator>(tempCount, m_tempAlloc);
405405
}
406406
else
@@ -446,6 +446,7 @@ IRBuilder::Build()
446446
#endif
447447

448448
lastOffset = m_func->m_workItem->GetLoopHeader()->endOffset;
449+
AssertOrFailFast(lastOffset < m_func->GetJITFunctionBody()->GetByteCodeLength());
449450
// Ret is created at lastOffset + 1, so we need lastOffset + 2 entries
450451
offsetToInstructionCount = lastOffset + 2;
451452

@@ -2721,6 +2722,7 @@ IRBuilder::BuildUnsigned1(Js::OpCode newOpcode, uint32 offset, uint32 num)
27212722

27222723
case Js::OpCode::ProfiledLoopStart:
27232724
{
2725+
AssertOrFailFast(num < m_func->GetJITFunctionBody()->GetLoopCount());
27242726
// If we're in profiling SimpleJit and jitting loop bodies, we need to keep this until lowering.
27252727
if (m_func->DoSimpleJitDynamicProfile() && m_func->GetJITFunctionBody()->DoJITLoopBody())
27262728
{
@@ -2771,6 +2773,7 @@ IRBuilder::BuildUnsigned1(Js::OpCode newOpcode, uint32 offset, uint32 num)
27712773

27722774
case Js::OpCode::ProfiledLoopEnd:
27732775
{
2776+
AssertOrFailFast(num < m_func->GetJITFunctionBody()->GetLoopCount());
27742777
// TODO: Decide whether we want the implicit loop call flags to be recorded in simplejitted loop bodies
27752778
if (m_func->DoSimpleJitDynamicProfile() && m_func->GetJITFunctionBody()->DoJITLoopBody())
27762779
{

0 commit comments

Comments
 (0)