Skip to content

Commit dbfb5bd

Browse files
committed
[MERGE #6087 @akroshg] April servicing update for ChakraCore
Merge pull request #6087 from akroshg:stage1904 Fixes CVE-2019-0739 CVE-2019-0806 CVE-2019-0810 CVE-2019-0812 CVE-2019-0829 CVE-2019-0860 CVE-2019-0861
2 parents a6f5a53 + a8df63b commit dbfb5bd

14 files changed

+80
-24
lines changed

Build/NuGet/.pack-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.11.7
1+
1.11.8

lib/Backend/GlobOpt.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3258,10 +3258,14 @@ GlobOpt::OptSrc(IR::Opnd *opnd, IR::Instr * *pInstr, Value **indirIndexValRef, I
32583258
}
32593259
originalPropertySym = sym->AsPropertySym();
32603260

3261-
// Dont give a vale to 'arguments' property sym to prevent field copy prop of 'arguments'
3261+
// Don't give a value to 'arguments' property sym to prevent field copy prop of 'arguments'
32623262
if (originalPropertySym->AsPropertySym()->m_propertyId == Js::PropertyIds::arguments &&
32633263
originalPropertySym->AsPropertySym()->m_fieldKind == PropertyKindData)
32643264
{
3265+
if (opnd->AsSymOpnd()->IsPropertySymOpnd())
3266+
{
3267+
this->FinishOptPropOp(instr, opnd->AsPropertySymOpnd());
3268+
}
32653269
return nullptr;
32663270
}
32673271

@@ -4813,7 +4817,7 @@ GlobOpt::ValueNumberDst(IR::Instr **pInstr, Value *src1Val, Value *src2Val)
48134817
}
48144818
else
48154819
{
4816-
return NewGenericValue(src1ValueInfo->Type().ToDefiniteAnyNumber(), dst);
4820+
return NewGenericValue(src1ValueInfo->Type().ToDefiniteAnyNumber().SetCanBeTaggedValue(true), dst);
48174821
}
48184822
break;
48194823

@@ -4874,7 +4878,7 @@ GlobOpt::ValueNumberDst(IR::Instr **pInstr, Value *src1Val, Value *src2Val)
48744878
{
48754879
valueType = ValueType::Number;
48764880
}
4877-
return CreateDstUntransferredValue(valueType, instr, src1Val, src2Val);
4881+
return CreateDstUntransferredValue(valueType.SetCanBeTaggedValue(true), instr, src1Val, src2Val);
48784882
}
48794883

48804884
case Js::OpCode::Add_A:
@@ -4908,12 +4912,12 @@ GlobOpt::ValueNumberDst(IR::Instr **pInstr, Value *src1Val, Value *src2Val)
49084912
{
49094913
// If one of them is a float, the result probably is a float instead of just int
49104914
// but should always be a number.
4911-
valueType = ValueType::Float;
4915+
valueType = ValueType::Float.SetCanBeTaggedValue(true);
49124916
}
49134917
else
49144918
{
49154919
// Could be int, could be number
4916-
valueType = ValueType::Number;
4920+
valueType = ValueType::Number.SetCanBeTaggedValue(true);
49174921
}
49184922
}
49194923
else if (src1ValueInfo->IsLikelyFloat() || src2ValueInfo->IsLikelyFloat())
@@ -4937,7 +4941,7 @@ GlobOpt::ValueNumberDst(IR::Instr **pInstr, Value *src1Val, Value *src2Val)
49374941
&& (src2Val && src2ValueInfo->IsNotString() && src2ValueInfo->IsPrimitive()))
49384942
{
49394943
// If src1 and src2 are not strings and primitive, add should yield a number.
4940-
valueType = ValueType::Number;
4944+
valueType = ValueType::Number.SetCanBeTaggedValue(true);
49414945
}
49424946
else if((src1Val && src1ValueInfo->IsLikelyString()) || (src2Val && src2ValueInfo->IsLikelyString()))
49434947
{
@@ -4958,7 +4962,7 @@ GlobOpt::ValueNumberDst(IR::Instr **pInstr, Value *src1Val, Value *src2Val)
49584962
ValueType divValueType = GetDivValueType(instr, src1Val, src2Val, false);
49594963
if (divValueType.IsLikelyInt() || divValueType.IsFloat())
49604964
{
4961-
return CreateDstUntransferredValue(divValueType, instr, src1Val, src2Val);
4965+
return CreateDstUntransferredValue(divValueType.SetCanBeTaggedValue(true), instr, src1Val, src2Val);
49624966
}
49634967
}
49644968
// fall-through
@@ -4990,11 +4994,11 @@ GlobOpt::ValueNumberDst(IR::Instr **pInstr, Value *src1Val, Value *src2Val)
49904994
// This should ideally be NewNumberAndLikelyFloatValue since we know the result is a number but not sure if it will
49914995
// be a float value. However, that Number/LikelyFloat value type doesn't exist currently and all the necessary
49924996
// checks are done for float values (tagged int checks, etc.) so it's sufficient to just create a float value here.
4993-
valueType = ValueType::Float;
4997+
valueType = ValueType::Float.SetCanBeTaggedValue(true);
49944998
}
49954999
else
49965000
{
4997-
valueType = ValueType::Number;
5001+
valueType = ValueType::Number.SetCanBeTaggedValue(true);
49985002
}
49995003

50005004
return CreateDstUntransferredValue(valueType, instr, src1Val, src2Val);

lib/Backend/GlobOptFields.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,10 +237,17 @@ GlobOpt::KillLiveElems(IR::IndirOpnd * indirOpnd, BVSparse<JitArenaAllocator> *
237237
this->KillAllFields(bv); // This also kills all property type values, as the same bit-vector tracks those stack syms
238238
SetAnyPropertyMayBeWrittenTo();
239239
}
240-
else if (inGlobOpt && indexOpnd && !indexOpnd->GetValueType().IsInt() && !currentBlock->globOptData.IsInt32TypeSpecialized(indexOpnd->m_sym))
240+
else if (inGlobOpt)
241241
{
242-
// Write/delete to a non-integer numeric index can't alias a name on the RHS of a dot, but it change object layout
243-
this->KillAllObjectTypes(bv);
242+
Value * indexValue = indexOpnd ? this->currentBlock->globOptData.FindValue(indexOpnd->GetSym()) : nullptr;
243+
ValueInfo * indexValueInfo = indexValue ? indexValue->GetValueInfo() : nullptr;
244+
int indexLowerBound = 0;
245+
246+
if (indirOpnd->GetOffset() < 0 || (indexOpnd && (!indexValueInfo || !indexValueInfo->TryGetIntConstantLowerBound(&indexLowerBound, false) || indexLowerBound < 0)))
247+
{
248+
// Write/delete to a non-integer numeric index can't alias a name on the RHS of a dot, but it change object layout
249+
this->KillAllObjectTypes(bv);
250+
}
244251
}
245252
}
246253

@@ -487,7 +494,9 @@ GlobOpt::ProcessFieldKills(IR::Instr *instr, BVSparse<JitArenaAllocator> *bv, bo
487494
case Js::OpCode::NewScObjectNoCtor:
488495
if (inGlobOpt)
489496
{
490-
KillObjectHeaderInlinedTypeSyms(this->currentBlock, false);
497+
// Opcodes that make an object into a prototype may break object-header-inlining and final type opt.
498+
// Kill all known object layouts.
499+
KillAllObjectTypes(bv);
491500
}
492501
break;
493502

lib/Backend/JITType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ JITType::BuildFromJsType(__in Js::Type * jsType, __out JITType * jitType)
3535

3636
Js::DynamicTypeHandler * handler = dynamicType->GetTypeHandler();
3737
data->handler.isObjectHeaderInlinedTypeHandler = handler->IsObjectHeaderInlinedTypeHandler();
38-
data->handler.isLocked = handler->GetIsLocked();
38+
data->handler.flags = handler->GetFlags();
3939
data->handler.inlineSlotCapacity = handler->GetInlineSlotCapacity();
4040
data->handler.offsetOfInlineSlots = handler->GetOffsetOfInlineSlots();
4141
data->handler.slotCapacity = handler->GetSlotCapacity();

lib/Backend/JITTypeHandler.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,13 @@ JITTypeHandler::IsObjectHeaderInlinedTypeHandler() const
1919
bool
2020
JITTypeHandler::IsLocked() const
2121
{
22-
return m_data.isLocked != FALSE;
22+
return Js::DynamicTypeHandler::GetIsLocked(m_data.flags);
23+
}
24+
25+
bool
26+
JITTypeHandler::IsPrototype() const
27+
{
28+
return Js::DynamicTypeHandler::GetIsPrototype(m_data.flags);
2329
}
2430

2531
uint16

lib/Backend/JITTypeHandler.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class JITTypeHandler
1212

1313
bool IsObjectHeaderInlinedTypeHandler() const;
1414
bool IsLocked() const;
15+
bool IsPrototype() const;
1516

1617
uint16 GetInlineSlotCapacity() const;
1718
uint16 GetOffsetOfInlineSlots() const;

lib/Backend/Lower.cpp

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6223,7 +6223,7 @@ Lowerer::GenerateLdFldWithCachedType(IR::Instr * instrLdFld, bool* continueAsHel
62236223

62246224
// Load the value from the slot, getting the slot ID from the cache.
62256225
uint16 index = propertySymOpnd->GetSlotIndex();
6226-
Assert(index != -1);
6226+
AssertOrFailFast(index != (uint16)-1);
62276227

62286228
if (opndSlotArray->IsRegOpnd())
62296229
{
@@ -7204,7 +7204,7 @@ Lowerer::GenerateDirectFieldStore(IR::Instr* instrStFld, IR::PropertySymOpnd* pr
72047204

72057205
// Store the value to the slot, getting the slot index from the cache.
72067206
uint16 index = propertySymOpnd->GetSlotIndex();
7207-
Assert(index != -1);
7207+
AssertOrFailFast(index != (uint16)-1);
72087208

72097209
#if defined(RECYCLER_WRITE_BARRIER_JIT) && (defined(_M_IX86) || defined(_M_AMD64))
72107210
if (opndSlotArray->IsRegOpnd())
@@ -7353,6 +7353,19 @@ Lowerer::GenerateStFldWithCachedType(IR::Instr *instrStFld, bool* continueAsHelp
73537353
{
73547354
Assert(labelTypeCheckFailed == nullptr && labelBothTypeChecksFailed == nullptr);
73557355
AssertMsg(!instrStFld->HasBailOutInfo(), "Why does a direct field store have bailout?");
7356+
7357+
if (propertySymOpnd->HasInitialType() && propertySymOpnd->HasFinalType())
7358+
{
7359+
bool isPrototypeTypeHandler = propertySymOpnd->GetInitialType()->GetTypeHandler()->IsPrototype();
7360+
if (isPrototypeTypeHandler)
7361+
{
7362+
LoadScriptContext(instrStFld);
7363+
m_lowererMD.LoadHelperArgument(instrStFld, IR::IntConstOpnd::New(propertySymOpnd->GetPropertyId(), TyInt32, m_func, true));
7364+
IR::Instr * invalidateCallInstr = IR::Instr::New(Js::OpCode::Call, m_func);
7365+
instrStFld->InsertBefore(invalidateCallInstr);
7366+
m_lowererMD.ChangeToHelperCall(invalidateCallInstr, IR::HelperInvalidateProtoCaches);
7367+
}
7368+
}
73567369
instrStFld->Remove();
73577370
return true;
73587371
}
@@ -8177,6 +8190,16 @@ Lowerer::GenerateFieldStoreWithTypeChange(IR::Instr * instrStFld, IR::PropertySy
81778190

81788191
// Now do the store.
81798192
GenerateDirectFieldStore(instrStFld, propertySymOpnd);
8193+
8194+
bool isPrototypeTypeHandler = initialType->GetTypeHandler()->IsPrototype();
8195+
if (isPrototypeTypeHandler)
8196+
{
8197+
LoadScriptContext(instrStFld);
8198+
m_lowererMD.LoadHelperArgument(instrStFld, IR::IntConstOpnd::New(propertySymOpnd->GetPropertyId(), TyInt32, m_func, true));
8199+
IR::Instr * invalidateCallInstr = IR::Instr::New(Js::OpCode::Call, m_func);
8200+
instrStFld->InsertBefore(invalidateCallInstr);
8201+
m_lowererMD.ChangeToHelperCall(invalidateCallInstr, IR::HelperInvalidateProtoCaches);
8202+
}
81808203
}
81818204

81828205
bool

lib/Common/ChakraCoreVersion.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
// ChakraCore version number definitions (used in ChakraCore binary metadata)
1818
#define CHAKRA_CORE_MAJOR_VERSION 1
1919
#define CHAKRA_CORE_MINOR_VERSION 11
20-
#define CHAKRA_CORE_PATCH_VERSION 7
20+
#define CHAKRA_CORE_PATCH_VERSION 8
2121
#define CHAKRA_CORE_VERSION_RELEASE_QFE 0 // Redundant with PATCH_VERSION. Keep this value set to 0.
2222

2323
// -------------

lib/JITIDL/JITTypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ typedef IDL_DEF([ref]) PSCRIPTCONTEXT_HANDLE * PPSCRIPTCONTEXT_HANDLE;
9090
typedef struct TypeHandlerIDL
9191
{
9292
IDL_Field(boolean) isObjectHeaderInlinedTypeHandler;
93-
IDL_Field(boolean) isLocked;
93+
IDL_Field(unsigned char) flags;
9494

9595
IDL_Field(unsigned short) inlineSlotCapacity;
9696
IDL_Field(unsigned short) offsetOfInlineSlots;

lib/Runtime/Language/JavascriptOperators.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9582,6 +9582,11 @@ using namespace Js;
95829582

95839583
Var result = CALL_ENTRYPOINT(threadContext, marshalledFunction->GetEntryPoint(), function, CallInfo(flags, 2), thisVar, putValue);
95849584
Assert(result);
9585+
9586+
// Set implicit call flags so we bail out if we're trying to propagate the stored value forward. We can't count on the getter/setter
9587+
// to produce the stored value on a LdFld.
9588+
threadContext->AddImplicitCallFlags(ImplicitCall_Accessor);
9589+
95859590
return nullptr;
95869591
});
95879592
}

0 commit comments

Comments
 (0)