From af10b8035e355e850b7a8ffa28fe58dddda41328 Mon Sep 17 00:00:00 2001 From: win7-7 Date: Wed, 12 Oct 2022 23:29:41 +0300 Subject: [PATCH] More security fixes toward 67 version. More security fixes toward 67 version. --- js/src/builtin/TypedObject.cpp | 4 +--- js/src/jit/JitFrames.cpp | 32 +++++++++++++++++++++++++++++++- js/src/jsgc.cpp | 20 +++++++++++++++++--- js/src/vm/Interpreter.cpp | 30 +++++++++++++++++++++++++++++- 4 files changed, 78 insertions(+), 8 deletions(-) diff --git a/js/src/builtin/TypedObject.cpp b/js/src/builtin/TypedObject.cpp index 10ae8902dd..c79e8b90c6 100644 --- a/js/src/builtin/TypedObject.cpp +++ b/js/src/builtin/TypedObject.cpp @@ -939,9 +939,7 @@ StructMetaTypeDescr::create(JSContext* cx, if (!CreateTraceList(cx, descr)) return nullptr; - if (!cx->zone()->addTypeDescrObject(cx, descr) || - !cx->zone()->addTypeDescrObject(cx, fieldTypeVec)) - { + if (!cx->zone()->addTypeDescrObject(cx, descr)) { ReportOutOfMemory(cx); return nullptr; } diff --git a/js/src/jit/JitFrames.cpp b/js/src/jit/JitFrames.cpp index 47b6d107f6..1da718d475 100644 --- a/js/src/jit/JitFrames.cpp +++ b/js/src/jit/JitFrames.cpp @@ -444,6 +444,10 @@ HandleExceptionIon(JSContext* cx, const InlineFrameIterator& frame, ResumeFromEx switch (tn->kind) { case JSTRY_FOR_IN: case JSTRY_DESTRUCTURING_ITERCLOSE: + // See corresponding comment in ProcessTryNotes. + if (inForOfIterClose) + break; + MOZ_ASSERT_IF(tn->kind == JSTRY_FOR_IN, JSOp(*(script->main() + tn->start + tn->length)) == JSOP_ENDITER); CloseLiveIteratorIon(cx, frame, tn); @@ -577,16 +581,34 @@ static void CloseLiveIteratorsBaselineForUncatchableException(JSContext* cx, const JitFrameIterator& frame, jsbytecode* pc) { + bool inForOfIterClose = false; for (TryNoteIterBaseline tni(cx, frame.baselineFrame(), pc); !tni.done(); ++tni) { JSTryNote* tn = *tni; + switch (tn->kind) { + case JSTRY_FOR_IN: { + // See corresponding comment in ProcessTryNotes. + if (inForOfIterClose) + break; - if (tn->kind == JSTRY_FOR_IN) { uint8_t* framePointer; uint8_t* stackPointer; BaselineFrameAndStackPointersFromTryNote(tn, frame, &framePointer, &stackPointer); Value iterValue(*(Value*) stackPointer); RootedObject iterObject(cx, &iterValue.toObject()); UnwindIteratorForUncatchableException(cx, iterObject); + break; + } + + case JSTRY_FOR_OF_ITERCLOSE: + inForOfIterClose = true; + break; + + case JSTRY_FOR_OF: + inForOfIterClose = false; + break; + + default: + break; } } } @@ -642,6 +664,10 @@ ProcessTryNotesBaseline(JSContext* cx, const JitFrameIterator& frame, Environmen } case JSTRY_FOR_IN: { + // See corresponding comment in ProcessTryNotes. + if (inForOfIterClose) + break; + uint8_t* framePointer; uint8_t* stackPointer; BaselineFrameAndStackPointersFromTryNote(tn, frame, &framePointer, &stackPointer); @@ -658,6 +684,10 @@ ProcessTryNotesBaseline(JSContext* cx, const JitFrameIterator& frame, Environmen } case JSTRY_DESTRUCTURING_ITERCLOSE: { + // See corresponding comment in ProcessTryNotes. + if (inForOfIterClose) + break; + uint8_t* framePointer; uint8_t* stackPointer; BaselineFrameAndStackPointersFromTryNote(tn, frame, &framePointer, &stackPointer); diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index f0cc3c40f0..7aa33c576e 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -2247,9 +2247,20 @@ ForegroundUpdateKinds(AllocKinds kinds) void GCRuntime::updateTypeDescrObjects(MovingTracer* trc, Zone* zone) { - zone->typeDescrObjects.sweep(); - for (auto r = zone->typeDescrObjects.all(); !r.empty(); r.popFront()) - UpdateCellPointers(trc, r.front()); + // We need to update each type descriptor object and any objects stored in + // its slots, since some of these contain array objects which also need to + // be updated. + zone->typeDescrObjects().sweep(); + + for (auto r = zone->typeDescrObjects().all(); !r.empty(); r.popFront()) { + NativeObject* obj = &r.front()->as(); + UpdateCellPointers(trc, obj); + for (size_t i = 0; i < obj->slotSpan(); i++) { + Value value = obj->getSlot(i); + if (value.isObject()) + UpdateCellPointers(trc, &value.toObject()); + } + } } void @@ -5475,6 +5486,9 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea MOZ_FALLTHROUGH; case State::Sweep: + for (const CooperatingContext& target : rt->cooperatingContexts()) + AutoGCRooter::traceAllWrappers(target, &marker); + if (performSweepActions(budget, lock) == NotFinished) break; diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp index bd41bb38b9..4d32cbbd4f 100644 --- a/js/src/vm/Interpreter.cpp +++ b/js/src/vm/Interpreter.cpp @@ -1018,11 +1018,29 @@ UnwindIteratorsForUncatchableException(JSContext* cx, const InterpreterRegs& reg { // c.f. the regular (catchable) TryNoteIterInterpreter loop in // ProcessTryNotes. + bool inForOfIterClose = false; for (TryNoteIterInterpreter tni(cx, regs); !tni.done(); ++tni) { JSTryNote* tn = *tni; - if (tn->kind == JSTRY_FOR_IN) { + switch (tn->kind) { + case JSTRY_FOR_IN: { + // See corresponding comment in ProcessTryNotes. + if (inForOfIterClose) + break; Value* sp = regs.spForStackDepth(tn->stackDepth); UnwindIteratorForUncatchableException(cx, &sp[-1].toObject()); + break; + } + + case JSTRY_FOR_OF_ITERCLOSE: + inForOfIterClose = true; + break; + + case JSTRY_FOR_OF: + inForOfIterClose = false; + break; + + default: + break; } } } @@ -1083,6 +1101,12 @@ ProcessTryNotes(JSContext* cx, EnvironmentIter& ei, InterpreterRegs& regs) return FinallyContinuation; case JSTRY_FOR_IN: { + // Don't let (extra) values pushed on the stack while closing a + // for-of iterator confuse us into thinking we still have to close + // an inner for-in iterator. + if (inForOfIterClose) + break; + /* This is similar to JSOP_ENDITER in the interpreter loop. */ DebugOnly pc = regs.fp()->script()->main() + tn->start + tn->length; MOZ_ASSERT(JSOp(*pc) == JSOP_ENDITER); @@ -1101,6 +1125,10 @@ ProcessTryNotes(JSContext* cx, EnvironmentIter& ei, InterpreterRegs& regs) } case JSTRY_DESTRUCTURING_ITERCLOSE: { + // See note above. + if (inForOfIterClose) + break; + // Whether the destructuring iterator is done is at the top of the // stack. The iterator object is second from the top. MOZ_ASSERT(tn->stackDepth > 1);