diff options
Diffstat (limited to 'gnu/packages/patches/icecat-CVE-2015-2724-pt2.patch')
-rw-r--r-- | gnu/packages/patches/icecat-CVE-2015-2724-pt2.patch | 391 |
1 files changed, 391 insertions, 0 deletions
diff --git a/gnu/packages/patches/icecat-CVE-2015-2724-pt2.patch b/gnu/packages/patches/icecat-CVE-2015-2724-pt2.patch new file mode 100644 index 0000000000..486e92c66d --- /dev/null +++ b/gnu/packages/patches/icecat-CVE-2015-2724-pt2.patch @@ -0,0 +1,391 @@ +From 99641aa4446dc9df04dcfeede8b49ff03abcac42 Mon Sep 17 00:00:00 2001 +From: Jan de Mooij <jdemooij@mozilla.com> +Date: Thu, 28 May 2015 10:16:24 +0200 +Subject: [PATCH] Bug 1160884 - Add KeepAlive instructions after elements/slots + uses. r=nbp, a=abillings + +--- + js/src/jit/CodeGenerator.cpp | 7 ++ + js/src/jit/CodeGenerator.h | 1 + + js/src/jit/Ion.cpp | 7 ++ + js/src/jit/IonAnalysis.cpp | 112 ++++++++++++++++++++++++++++++++ + js/src/jit/IonAnalysis.h | 3 + + js/src/jit/LIR-Common.h | 14 ++++ + js/src/jit/LOpcodes.h | 1 + + js/src/jit/Lowering.cpp | 9 +++ + js/src/jit/Lowering.h | 1 + + js/src/jit/MIR.h | 26 ++++++++ + js/src/jit/MOpcodes.h | 1 + + js/src/jit/ParallelSafetyAnalysis.cpp | 1 + + js/src/jit/shared/Lowering-shared-inl.h | 8 ++- + js/src/jit/shared/Lowering-shared.h | 1 + + js/src/vm/TraceLogging.h | 3 +- + 15 files changed, 193 insertions(+), 2 deletions(-) + +diff --git a/js/src/jit/CodeGenerator.cpp b/js/src/jit/CodeGenerator.cpp +index 5dff9df..7364178 100644 +--- a/js/src/jit/CodeGenerator.cpp ++++ b/js/src/jit/CodeGenerator.cpp +@@ -1476,6 +1476,13 @@ CodeGenerator::visitPointer(LPointer* lir) + } + + bool ++CodeGenerator::visitKeepAliveObject(LKeepAliveObject* lir) ++{ ++ // No-op. ++ return true; ++} ++ ++bool + CodeGenerator::visitSlots(LSlots* lir) + { + Address slots(ToRegister(lir->object()), JSObject::offsetOfSlots()); +diff --git a/js/src/jit/CodeGenerator.h b/js/src/jit/CodeGenerator.h +index 95fb33b..e3b4fd7 100644 +--- a/js/src/jit/CodeGenerator.h ++++ b/js/src/jit/CodeGenerator.h +@@ -106,6 +106,7 @@ class CodeGenerator : public CodeGeneratorSpecific + bool visitLambdaForSingleton(LLambdaForSingleton* lir); + bool visitLambdaPar(LLambdaPar* lir); + bool visitPointer(LPointer* lir); ++ bool visitKeepAliveObject(LKeepAliveObject* lir); + bool visitSlots(LSlots* lir); + bool visitStoreSlotV(LStoreSlotV* store); + bool visitElements(LElements* lir); +diff --git a/js/src/jit/Ion.cpp b/js/src/jit/Ion.cpp +index 015d387..1551a80 100644 +--- a/js/src/jit/Ion.cpp ++++ b/js/src/jit/Ion.cpp +@@ -1536,6 +1536,13 @@ OptimizeMIR(MIRGenerator* mir) + AssertGraphCoherency(graph); + } + ++ if (!mir->compilingAsmJS()) { ++ AutoTraceLog log(logger, TraceLogger::AddKeepAliveInstructions); ++ AddKeepAliveInstructions(graph); ++ IonSpewPass("Add KeepAlive Instructions"); ++ AssertGraphCoherency(graph); ++ } ++ + return true; + } + +diff --git a/js/src/jit/IonAnalysis.cpp b/js/src/jit/IonAnalysis.cpp +index 8965724..af58aae 100644 +--- a/js/src/jit/IonAnalysis.cpp ++++ b/js/src/jit/IonAnalysis.cpp +@@ -1971,6 +1971,118 @@ jit::UnsplitEdges(LIRGraph* lir) + return true; + } + ++static bool ++NeedsKeepAlive(MInstruction* slotsOrElements, MInstruction* use) ++{ ++ MOZ_ASSERT(slotsOrElements->type() == MIRType_Elements || ++ slotsOrElements->type() == MIRType_Slots); ++ ++ if (slotsOrElements->block() != use->block()) ++ return true; ++ ++ MBasicBlock* block = use->block(); ++ MInstructionIterator iter(block->begin(slotsOrElements)); ++ MOZ_ASSERT(*iter == slotsOrElements); ++ ++iter; ++ ++ while (true) { ++ if (*iter == use) ++ return false; ++ ++ switch (iter->op()) { ++ case MDefinition::Op_Nop: ++ case MDefinition::Op_Constant: ++ case MDefinition::Op_KeepAliveObject: ++ case MDefinition::Op_Unbox: ++ case MDefinition::Op_LoadSlot: ++ case MDefinition::Op_StoreSlot: ++ case MDefinition::Op_LoadFixedSlot: ++ case MDefinition::Op_StoreFixedSlot: ++ case MDefinition::Op_LoadElement: ++ case MDefinition::Op_StoreElement: ++ case MDefinition::Op_InitializedLength: ++ case MDefinition::Op_ArrayLength: ++ case MDefinition::Op_BoundsCheck: ++ iter++; ++ break; ++ default: ++ return true; ++ } ++ } ++ ++ MOZ_CRASH("Unreachable"); ++} ++ ++void ++jit::AddKeepAliveInstructions(MIRGraph& graph) ++{ ++ for (MBasicBlockIterator i(graph.begin()); i != graph.end(); i++) { ++ MBasicBlock* block = *i; ++ ++ for (MInstructionIterator insIter(block->begin()); insIter != block->end(); insIter++) { ++ MInstruction* ins = *insIter; ++ if (ins->type() != MIRType_Elements && ins->type() != MIRType_Slots) ++ continue; ++ ++ MDefinition* ownerObject; ++ switch (ins->op()) { ++ case MDefinition::Op_ConstantElements: ++ case MDefinition::Op_NewSlots: ++ continue; ++ case MDefinition::Op_ConvertElementsToDoubles: ++ // EliminateRedundantChecks should have replaced all uses. ++ MOZ_ASSERT(!ins->hasUses()); ++ continue; ++ case MDefinition::Op_Elements: ++ case MDefinition::Op_TypedArrayElements: ++ case MDefinition::Op_TypedObjectElements: ++ MOZ_ASSERT(ins->numOperands() == 1); ++ ownerObject = ins->getOperand(0); ++ break; ++ case MDefinition::Op_Slots: ++ ownerObject = ins->toSlots()->object(); ++ break; ++ default: ++ MOZ_CRASH("Unexpected op"); ++ } ++ ++ MOZ_ASSERT(ownerObject->type() == MIRType_Object); ++ ++ if (ownerObject->isConstant()) { ++ // Constants are kept alive by other pointers, for instance ++ // ImmGCPtr in JIT code. ++ continue; ++ } ++ ++ for (MUseDefIterator uses(ins); uses; uses++) { ++ MInstruction* use = uses.def()->toInstruction(); ++ ++ if (use->isStoreElementHole()) { ++ // StoreElementHole has an explicit object operand. If GVN ++ // is disabled, we can get different unbox instructions with ++ // the same object as input, so we check for that case. ++ MOZ_ASSERT_IF(!use->toStoreElementHole()->object()->isUnbox() && !ownerObject->isUnbox(), ++ use->toStoreElementHole()->object() == ownerObject); ++ continue; ++ } ++ ++ if (use->isInArray()) { ++ // See StoreElementHole case above. ++ MOZ_ASSERT_IF(!use->toInArray()->object()->isUnbox() && !ownerObject->isUnbox(), ++ use->toInArray()->object() == ownerObject); ++ continue; ++ } ++ ++ if (!NeedsKeepAlive(ins, use)) ++ continue; ++ ++ MKeepAliveObject* keepAlive = MKeepAliveObject::New(graph.alloc(), ownerObject); ++ use->block()->insertAfter(use, keepAlive); ++ } ++ } ++ } ++} ++ + bool + LinearSum::multiply(int32_t scale) + { +diff --git a/js/src/jit/IonAnalysis.h b/js/src/jit/IonAnalysis.h +index aabf835..a320418 100644 +--- a/js/src/jit/IonAnalysis.h ++++ b/js/src/jit/IonAnalysis.h +@@ -64,6 +64,9 @@ AssertExtendedGraphCoherency(MIRGraph& graph); + bool + EliminateRedundantChecks(MIRGraph& graph); + ++void ++AddKeepAliveInstructions(MIRGraph& graph); ++ + bool + UnsplitEdges(LIRGraph* lir); + +diff --git a/js/src/jit/LIR-Common.h b/js/src/jit/LIR-Common.h +index 5fe0ee9..6b03a42 100644 +--- a/js/src/jit/LIR-Common.h ++++ b/js/src/jit/LIR-Common.h +@@ -3591,6 +3591,20 @@ class LImplicitThis : public LInstructionHelper<BOX_PIECES, 1, 0> + } + }; + ++class LKeepAliveObject : public LInstructionHelper<0, 1, 0> ++{ ++ public: ++ LIR_HEADER(KeepAliveObject) ++ ++ explicit LKeepAliveObject(const LAllocation& object) { ++ setOperand(0, object); ++ } ++ ++ const LAllocation* object() { ++ return getOperand(0); ++ } ++}; ++ + // Load the "slots" member out of a JSObject. + // Input: JSObject pointer + // Output: slots pointer +diff --git a/js/src/jit/LOpcodes.h b/js/src/jit/LOpcodes.h +index cd7eef8..424b22c 100644 +--- a/js/src/jit/LOpcodes.h ++++ b/js/src/jit/LOpcodes.h +@@ -166,6 +166,7 @@ + _(LambdaForSingleton) \ + _(LambdaPar) \ + _(ImplicitThis) \ ++ _(KeepAliveObject) \ + _(Slots) \ + _(Elements) \ + _(ConvertElementsToDoubles) \ +diff --git a/js/src/jit/Lowering.cpp b/js/src/jit/Lowering.cpp +index d671fd4..c0d434e 100644 +--- a/js/src/jit/Lowering.cpp ++++ b/js/src/jit/Lowering.cpp +@@ -2110,6 +2110,15 @@ LIRGenerator::visitImplicitThis(MImplicitThis* ins) + } + + bool ++LIRGenerator::visitKeepAliveObject(MKeepAliveObject* ins) ++{ ++ MDefinition* obj = ins->object(); ++ MOZ_ASSERT(obj->type() == MIRType_Object); ++ ++ return add(new(alloc()) LKeepAliveObject(useKeepalive(obj)), ins); ++} ++ ++bool + LIRGenerator::visitSlots(MSlots* ins) + { + return define(new(alloc()) LSlots(useRegisterAtStart(ins->object())), ins); +diff --git a/js/src/jit/Lowering.h b/js/src/jit/Lowering.h +index ea50cab..a60dc30 100644 +--- a/js/src/jit/Lowering.h ++++ b/js/src/jit/Lowering.h +@@ -160,6 +160,7 @@ class LIRGenerator : public LIRGeneratorSpecific + bool visitLambdaArrow(MLambdaArrow* ins); + bool visitLambdaPar(MLambdaPar* ins); + bool visitImplicitThis(MImplicitThis* ins); ++ bool visitKeepAliveObject(MKeepAliveObject* ins); + bool visitSlots(MSlots* ins); + bool visitElements(MElements* ins); + bool visitConstantElements(MConstantElements* ins); +diff --git a/js/src/jit/MIR.h b/js/src/jit/MIR.h +index 48e1dfb..a6060a2 100644 +--- a/js/src/jit/MIR.h ++++ b/js/src/jit/MIR.h +@@ -5790,6 +5790,32 @@ class MSetTypedObjectOffset + } + }; + ++class MKeepAliveObject ++ : public MUnaryInstruction, ++ public SingleObjectPolicy ++{ ++ explicit MKeepAliveObject(MDefinition* object) ++ : MUnaryInstruction(object) ++ { ++ setResultType(MIRType_None); ++ setGuard(); ++ } ++ ++ public: ++ INSTRUCTION_HEADER(KeepAliveObject) ++ ++ static MKeepAliveObject* New(TempAllocator& alloc, MDefinition* object) { ++ return new(alloc) MKeepAliveObject(object); ++ } ++ ++ MDefinition* object() const { ++ return getOperand(0); ++ } ++ TypePolicy* typePolicy() { ++ return this; ++ } ++}; ++ + // Perform !-operation + class MNot + : public MUnaryInstruction, +diff --git a/js/src/jit/MOpcodes.h b/js/src/jit/MOpcodes.h +index 83b9e63..cfc3895 100644 +--- a/js/src/jit/MOpcodes.h ++++ b/js/src/jit/MOpcodes.h +@@ -110,6 +110,7 @@ namespace jit { + _(Lambda) \ + _(LambdaArrow) \ + _(ImplicitThis) \ ++ _(KeepAliveObject) \ + _(Slots) \ + _(Elements) \ + _(ConstantElements) \ +diff --git a/js/src/jit/ParallelSafetyAnalysis.cpp b/js/src/jit/ParallelSafetyAnalysis.cpp +index a6a1202..13c577b 100644 +--- a/js/src/jit/ParallelSafetyAnalysis.cpp ++++ b/js/src/jit/ParallelSafetyAnalysis.cpp +@@ -199,6 +199,7 @@ class ParallelSafetyVisitor : public MInstructionVisitor + CUSTOM_OP(Lambda) + UNSAFE_OP(LambdaArrow) + UNSAFE_OP(ImplicitThis) ++ SAFE_OP(KeepAliveObject) + SAFE_OP(Slots) + SAFE_OP(Elements) + SAFE_OP(ConstantElements) +diff --git a/js/src/jit/shared/Lowering-shared-inl.h b/js/src/jit/shared/Lowering-shared-inl.h +index 17bb74a..832cc61 100644 +--- a/js/src/jit/shared/Lowering-shared-inl.h ++++ b/js/src/jit/shared/Lowering-shared-inl.h +@@ -372,11 +372,17 @@ LIRGeneratorShared::useStorableAtStart(MDefinition* mir) + #endif + + LAllocation ++LIRGeneratorShared::useKeepalive(MDefinition* mir) ++{ ++ return use(mir, LUse(LUse::KEEPALIVE)); ++} ++ ++LAllocation + LIRGeneratorShared::useKeepaliveOrConstant(MDefinition* mir) + { + if (mir->isConstant()) + return LAllocation(mir->toConstant()->vp()); +- return use(mir, LUse(LUse::KEEPALIVE)); ++ return useKeepalive(mir); + } + + LUse +diff --git a/js/src/jit/shared/Lowering-shared.h b/js/src/jit/shared/Lowering-shared.h +index 4bd13b0..b23d20e 100644 +--- a/js/src/jit/shared/Lowering-shared.h ++++ b/js/src/jit/shared/Lowering-shared.h +@@ -85,6 +85,7 @@ class LIRGeneratorShared : public MInstructionVisitorWithDefaults + // this is a generic "things we can expect to write into memory in 1 instruction" + inline LAllocation useStorable(MDefinition* mir); + inline LAllocation useStorableAtStart(MDefinition* mir); ++ inline LAllocation useKeepalive(MDefinition* mir); + inline LAllocation useKeepaliveOrConstant(MDefinition* mir); + inline LAllocation useRegisterOrConstant(MDefinition* mir); + inline LAllocation useRegisterOrConstantAtStart(MDefinition* mir); +diff --git a/js/src/vm/TraceLogging.h b/js/src/vm/TraceLogging.h +index 4c2ebfe..8447679 100644 +--- a/js/src/vm/TraceLogging.h ++++ b/js/src/vm/TraceLogging.h +@@ -145,7 +145,8 @@ namespace jit { + _(EffectiveAddressAnalysis) \ + _(EliminateDeadCode) \ + _(EdgeCaseAnalysis) \ +- _(EliminateRedundantChecks) ++ _(EliminateRedundantChecks) \ ++ _(AddKeepAliveInstructions) + + class AutoTraceLog; + +-- +2.4.3 + |