From 9ed502c59c6456bf8984bb6de49472da69ef4c90 Mon Sep 17 00:00:00 2001 From: Ted Campbell Date: Sat, 07 Nov 2020 05:36:31 +0000 (2020-11-07) Subject: [PATCH] CVE-2020-26950 Simplify IonBuilder::createThisScripted. r=jandem,iain a=RyanVM --- js/src/jit/IonBuilder.cpp | 31 ++++++++----------------------- js/src/jit/IonIC.cpp | 8 ++++++++ 2 files changed, 16 insertions(+), 23 deletions(-) diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 1b2a62a268..865e7bb322 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -5206,31 +5206,16 @@ MDefinition* IonBuilder::createThisScripted(MDefinition* callee, // explicit operation in the bytecode, we cannot use resumeAfter(). // Getters may not override |prototype| fetching, so this operation is // indeed idempotent. - // - First try an idempotent property cache. - // - Upon failing idempotent property cache, we can't use a non-idempotent - // cache, therefore we fallback to CallGetProperty - // - // Note: both CallGetProperty and GetPropertyCache can trigger a GC, - // and thus invalidation. - MInstruction* getProto; - if (!invalidatedIdempotentCache()) { - MConstant* id = constant(StringValue(names().prototype)); - MGetPropertyCache* getPropCache = - MGetPropertyCache::New(alloc(), newTarget, id, - /* monitored = */ false); - getPropCache->setIdempotent(); - getProto = getPropCache; - } else { - MCallGetProperty* callGetProp = - MCallGetProperty::New(alloc(), newTarget, names().prototype); - callGetProp->setIdempotent(); - getProto = callGetProp; - } - current->add(getProto); - + // Note: GetPropertyCache can trigger a GC, and thus invalidation. + MConstant* id = constant(StringValue(names().prototype)); + MGetPropertyCache* getPropCache = + MGetPropertyCache::New(alloc(), newTarget, id, + /* monitored = */ false); + getPropCache->setIdempotent(); + current->add(getPropCache); // Create this from prototype MCreateThisWithProto* createThis = - MCreateThisWithProto::New(alloc(), callee, newTarget, getProto); + MCreateThisWithProto::New(alloc(), callee, newTarget, getPropCache); current->add(createThis); return createThis; diff --git a/js/src/jit/IonIC.cpp b/js/src/jit/IonIC.cpp index 2c3ba44782..3cd06a13e7 100644 --- a/js/src/jit/IonIC.cpp +++ b/js/src/jit/IonIC.cpp @@ -216,6 +216,14 @@ bool IonGetPropertyIC::update(JSContext* cx, HandleScript outerScript, if (outerScript->hasIonScript()) { Invalidate(cx, outerScript); } + // IonBuilder::createScriptedThis does not use InvalidedIdempotentCache + // flag so prevent bailout-loop by disabling Ion for the script. + MOZ_ASSERT(ic->kind() == CacheKind::GetProp); + if (idVal.toString()->asAtom().asPropertyName() == cx->names().prototype) { + if (val.isObject() && val.toObject().is()) { + outerScript->disableIon(); + } + } // We will redo the potentially effectful lookup in Baseline. return true; -- 2.27.0