diff --git a/backport-0001-CVE-2020-35113.patch b/backport-0001-CVE-2020-35113.patch new file mode 100644 index 0000000000000000000000000000000000000000..2b3314a43deae39d9cec0718a8ff1484e56e55de --- /dev/null +++ b/backport-0001-CVE-2020-35113.patch @@ -0,0 +1,372 @@ +From 76c686639568a0bad97ca3f9d80386d7778a1033 Mon Sep 17 00:00:00 2001 +From: jcristau jcristau@mozilla.com +Date: Thu, 24 Feb 2022 16:12:51 +0800 +Subject: [PATCH] 0001-backport-CVE-2020-35113 + +Conflict:NA +Reference:https://hg.mozilla.org/releases/mozilla-esr78/rev/bac0869c171b +--- + dom/media/ipc/GpuDecoderModule.cpp | 2 +- + dom/media/ipc/RemoteDecoderModule.cpp | 4 +- + dom/media/ipc/RemoteVideoDecoder.cpp | 14 +++---- + dom/media/ipc/RemoteVideoDecoder.h | 4 +- + gfx/layers/RotatedBuffer.cpp | 2 +- + gfx/layers/RotatedBuffer.h | 2 +- + gfx/layers/client/TextureClient.h | 5 ++- + gfx/layers/d3d11/TextureD3D11.cpp | 4 +- + gfx/layers/d3d11/TextureD3D11.h | 2 +- + gfx/layers/ipc/KnowsCompositor.h | 56 ++++++++++++++++++--------- + gfx/layers/ipc/ShadowLayers.cpp | 14 ++++--- + 11 files changed, 65 insertions(+), 44 deletions(-) + +diff --git a/dom/media/ipc/GpuDecoderModule.cpp b/dom/media/ipc/GpuDecoderModule.cpp +index 24fc644..60a34f7 100644 +--- a/dom/media/ipc/GpuDecoderModule.cpp ++++ b/dom/media/ipc/GpuDecoderModule.cpp +@@ -59,7 +59,7 @@ already_AddRefed GpuDecoderModule::CreateVideoDecoder( + AutoCompleteTask complete(&task); + result = child->InitIPDL( + aParams.VideoConfig(), aParams.mRate.mValue, aParams.mOptions, +- aParams.mKnowsCompositor->GetTextureFactoryIdentifier()); ++ Some(aParams.mKnowsCompositor->GetTextureFactoryIdentifier())); + }), + NS_DISPATCH_NORMAL); + task.Wait(); +diff --git a/dom/media/ipc/RemoteDecoderModule.cpp b/dom/media/ipc/RemoteDecoderModule.cpp +index d81fa11..87a5690 100644 +--- a/dom/media/ipc/RemoteDecoderModule.cpp ++++ b/dom/media/ipc/RemoteDecoderModule.cpp +@@ -177,8 +177,8 @@ already_AddRefed RemoteDecoderModule::CreateVideoDecoder( + result = child->InitIPDL( + aParams.VideoConfig(), aParams.mRate.mValue, aParams.mOptions, + aParams.mKnowsCompositor +- ? &aParams.mKnowsCompositor->GetTextureFactoryIdentifier() +- : nullptr); ++ ? Some(aParams.mKnowsCompositor->GetTextureFactoryIdentifier()) ++ : Nothing()); + if (NS_FAILED(result)) { + // Release RemoteVideoDecoderChild here, while we're on + // manager thread. Don't just let the RefPtr go out of scope. +diff --git a/dom/media/ipc/RemoteVideoDecoder.cpp b/dom/media/ipc/RemoteVideoDecoder.cpp +index 25c3451..d26edc5 100644 +--- a/dom/media/ipc/RemoteVideoDecoder.cpp ++++ b/dom/media/ipc/RemoteVideoDecoder.cpp +@@ -178,7 +178,7 @@ MediaResult RemoteVideoDecoderChild::ProcessOutput( + MediaResult RemoteVideoDecoderChild::InitIPDL( + const VideoInfo& aVideoInfo, float aFramerate, + const CreateDecoderParams::OptionSet& aOptions, +- const layers::TextureFactoryIdentifier* aIdentifier) { ++ Maybe aIdentifier) { + RefPtr manager = + RemoteDecoderManagerChild::GetRDDProcessSingleton(); + +@@ -199,9 +199,8 @@ MediaResult RemoteVideoDecoderChild::InitIPDL( + bool success = false; + nsCString errorDescription; + VideoDecoderInfoIPDL decoderInfo(aVideoInfo, aFramerate); +- Unused << manager->SendPRemoteDecoderConstructor(this, decoderInfo, aOptions, +- ToMaybe(aIdentifier), +- &success, &errorDescription); ++ Unused << manager->SendPRemoteDecoderConstructor( ++ this, decoderInfo, aOptions, aIdentifier, &success, &errorDescription); + + return success ? MediaResult(NS_OK) + : MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, errorDescription); +@@ -213,7 +212,7 @@ GpuRemoteVideoDecoderChild::GpuRemoteVideoDecoderChild() + MediaResult GpuRemoteVideoDecoderChild::InitIPDL( + const VideoInfo& aVideoInfo, float aFramerate, + const CreateDecoderParams::OptionSet& aOptions, +- const layers::TextureFactoryIdentifier& aIdentifier) { ++ Maybe aIdentifier) { + RefPtr manager = + RemoteDecoderManagerChild::GetGPUProcessSingleton(); + +@@ -239,9 +238,8 @@ MediaResult GpuRemoteVideoDecoderChild::InitIPDL( + bool success = false; + nsCString errorDescription; + VideoDecoderInfoIPDL decoderInfo(aVideoInfo, aFramerate); +- Unused << manager->SendPRemoteDecoderConstructor(this, decoderInfo, aOptions, +- Some(aIdentifier), &success, +- &errorDescription); ++ Unused << manager->SendPRemoteDecoderConstructor( ++ this, decoderInfo, aOptions, aIdentifier, &success, &errorDescription); + + return success ? MediaResult(NS_OK) + : MediaResult(NS_ERROR_DOM_MEDIA_FATAL_ERR, errorDescription); +diff --git a/dom/media/ipc/RemoteVideoDecoder.h b/dom/media/ipc/RemoteVideoDecoder.h +index 4c56627..ac1efd7 100644 +--- a/dom/media/ipc/RemoteVideoDecoder.h ++++ b/dom/media/ipc/RemoteVideoDecoder.h +@@ -26,7 +26,7 @@ class RemoteVideoDecoderChild : public RemoteDecoderChild { + MOZ_IS_CLASS_INIT + MediaResult InitIPDL(const VideoInfo& aVideoInfo, float aFramerate, + const CreateDecoderParams::OptionSet& aOptions, +- const layers::TextureFactoryIdentifier* aIdentifier); ++ Maybe aIdentifier); + + MediaResult ProcessOutput(const DecodedOutputIPDL& aDecodedData) override; + +@@ -44,7 +44,7 @@ class GpuRemoteVideoDecoderChild final : public RemoteVideoDecoderChild { + MOZ_IS_CLASS_INIT + MediaResult InitIPDL(const VideoInfo& aVideoInfo, float aFramerate, + const CreateDecoderParams::OptionSet& aOptions, +- const layers::TextureFactoryIdentifier& aIdentifier); ++ Maybe aIdentifier); + }; + + class RemoteVideoDecoderParent final : public RemoteDecoderParent { +diff --git a/gfx/layers/RotatedBuffer.cpp b/gfx/layers/RotatedBuffer.cpp +index 544fbe3..a1651f2 100644 +--- a/gfx/layers/RotatedBuffer.cpp ++++ b/gfx/layers/RotatedBuffer.cpp +@@ -439,7 +439,7 @@ void RemoteRotatedBuffer::Unlock() { + } + } + +-void RemoteRotatedBuffer::SyncWithObject(SyncObjectClient* aSyncObject) { ++void RemoteRotatedBuffer::SyncWithObject(RefPtr aSyncObject) { + mClient->SyncWithObject(aSyncObject); + if (mClientOnWhite) { + mClientOnWhite->SyncWithObject(aSyncObject); +diff --git a/gfx/layers/RotatedBuffer.h b/gfx/layers/RotatedBuffer.h +index bcd8fba..eaaa152 100644 +--- a/gfx/layers/RotatedBuffer.h ++++ b/gfx/layers/RotatedBuffer.h +@@ -316,7 +316,7 @@ class RemoteRotatedBuffer : public RotatedBuffer { + return mClientOnWhite; + } + +- void SyncWithObject(SyncObjectClient* aSyncObject); ++ void SyncWithObject(RefPtr aSyncObject); + void Clear(); + + private: +diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h +index 4f12c6e..c6e77a3 100644 +--- a/gfx/layers/client/TextureClient.h ++++ b/gfx/layers/client/TextureClient.h +@@ -25,6 +25,7 @@ + #include "mozilla/layers/ISurfaceAllocator.h" + #include "mozilla/layers/LayersTypes.h" + #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor ++#include "mozilla/layers/SyncObject.h" + #include "mozilla/mozalloc.h" // for operator delete + #include "mozilla/gfx/CriticalSection.h" + #include "mozilla/webrender/WebRenderTypes.h" +@@ -297,7 +298,7 @@ class TextureData { + + virtual bool ReadBack(TextureReadbackSink* aReadbackSink) { return false; } + +- virtual void SyncWithObject(SyncObjectClient* aSyncObject){}; ++ virtual void SyncWithObject(RefPtr aSyncObject){}; + + virtual TextureFlags GetTextureFlags() const { + return TextureFlags::NO_FLAGS; +@@ -593,7 +594,7 @@ class TextureClient : public AtomicRefCountedWithFinalize { + mReadbackSink = aReadbackSink; + } + +- void SyncWithObject(SyncObjectClient* aSyncObject) { ++ void SyncWithObject(RefPtr aSyncObject) { + mData->SyncWithObject(aSyncObject); + } + +diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp +index 46efa51..ecd9e81 100644 +--- a/gfx/layers/d3d11/TextureD3D11.cpp ++++ b/gfx/layers/d3d11/TextureD3D11.cpp +@@ -357,7 +357,7 @@ void D3D11TextureData::FillInfo(TextureData::Info& aInfo) const { + aInfo.hasSynchronization = mHasSynchronization; + } + +-void D3D11TextureData::SyncWithObject(SyncObjectClient* aSyncObject) { ++void D3D11TextureData::SyncWithObject(RefPtr aSyncObject) { + if (!aSyncObject || mHasSynchronization) { + // When we have per texture synchronization we sync using the keyed mutex. + return; +@@ -365,7 +365,7 @@ void D3D11TextureData::SyncWithObject(SyncObjectClient* aSyncObject) { + + MOZ_ASSERT(aSyncObject->GetSyncType() == SyncObjectClient::SyncType::D3D11); + SyncObjectD3D11Client* sync = +- static_cast(aSyncObject); ++ static_cast(aSyncObject.get()); + sync->RegisterTexture(mTexture); + } + +diff --git a/gfx/layers/d3d11/TextureD3D11.h b/gfx/layers/d3d11/TextureD3D11.h +index 190332e..adfc95f 100644 +--- a/gfx/layers/d3d11/TextureD3D11.h ++++ b/gfx/layers/d3d11/TextureD3D11.h +@@ -68,7 +68,7 @@ class D3D11TextureData final : public TextureData { + LayersBackend aLayersBackend, TextureFlags aFlags, + TextureAllocationFlags aAllocFlags) const override; + +- void SyncWithObject(SyncObjectClient* aSyncObject) override; ++ void SyncWithObject(RefPtr aSyncObject) override; + + ID3D11Texture2D* GetD3D11Texture() const { return mTexture; } + +diff --git a/gfx/layers/ipc/KnowsCompositor.h b/gfx/layers/ipc/KnowsCompositor.h +index 6d7e9b6..052d456 100644 +--- a/gfx/layers/ipc/KnowsCompositor.h ++++ b/gfx/layers/ipc/KnowsCompositor.h +@@ -10,11 +10,12 @@ + #include "mozilla/layers/LayersTypes.h" // for LayersBackend + #include "mozilla/layers/CompositorTypes.h" + #include "nsExpirationTracker.h" ++#include "mozilla/DataMutex.h" ++#include "mozilla/layers/SyncObject.h" + + namespace mozilla { + namespace layers { + +-class SyncObjectClient; + class TextureForwarder; + class LayersIPCActor; + class ImageBridgeChild; +@@ -60,7 +61,10 @@ class KnowsCompositor { + + void IdentifyTextureHost(const TextureFactoryIdentifier& aIdentifier); + +- SyncObjectClient* GetSyncObject() { return mSyncObject; } ++ RefPtr GetSyncObject() { ++ auto lock = mData.Lock(); ++ return lock.ref().mSyncObject; ++ } + + /// And by "thread-safe" here we merely mean "okay to hold strong references + /// to from multiple threads". Not all methods actually are thread-safe. +@@ -71,7 +75,8 @@ class KnowsCompositor { + } + + int32_t GetMaxTextureSize() const { +- return mTextureFactoryIdentifier.mMaxTextureSize; ++ auto lock = mData.Lock(); ++ return lock.ref().mTextureFactoryIdentifier.mMaxTextureSize; + } + + /** +@@ -80,45 +85,57 @@ class KnowsCompositor { + * be queried once and will not change until Gecko is restarted. + */ + LayersBackend GetCompositorBackendType() const { +- return mTextureFactoryIdentifier.mParentBackend; ++ auto lock = mData.Lock(); ++ return lock.ref().mTextureFactoryIdentifier.mParentBackend; + } + + bool SupportsTextureBlitting() const { +- return mTextureFactoryIdentifier.mSupportsTextureBlitting; ++ auto lock = mData.Lock(); ++ return lock.ref().mTextureFactoryIdentifier.mSupportsTextureBlitting; + } + + bool SupportsPartialUploads() const { +- return mTextureFactoryIdentifier.mSupportsPartialUploads; ++ auto lock = mData.Lock(); ++ return lock.ref().mTextureFactoryIdentifier.mSupportsPartialUploads; + } + + bool SupportsComponentAlpha() const { +- return mTextureFactoryIdentifier.mSupportsComponentAlpha; ++ auto lock = mData.Lock(); ++ return lock.ref().mTextureFactoryIdentifier.mSupportsComponentAlpha; + } + + bool SupportsTextureDirectMapping() const { +- return mTextureFactoryIdentifier.mSupportsTextureDirectMapping; ++ auto lock = mData.Lock(); ++ return lock.ref().mTextureFactoryIdentifier.mSupportsTextureDirectMapping; + } + + bool SupportsD3D11() const { +- return GetCompositorBackendType() == layers::LayersBackend::LAYERS_D3D11 || +- (GetCompositorBackendType() == layers::LayersBackend::LAYERS_WR && +- GetCompositorUseANGLE()); ++ auto lock = mData.Lock(); ++ return lock.ref().mTextureFactoryIdentifier.mParentBackend == ++ layers::LayersBackend::LAYERS_D3D11 || ++ (lock.ref().mTextureFactoryIdentifier.mParentBackend == ++ layers::LayersBackend::LAYERS_WR && ++ lock.ref().mTextureFactoryIdentifier.mCompositorUseANGLE); + } + + bool GetCompositorUseANGLE() const { +- return mTextureFactoryIdentifier.mCompositorUseANGLE; ++ auto lock = mData.Lock(); ++ return lock.ref().mTextureFactoryIdentifier.mCompositorUseANGLE; + } + + bool GetCompositorUseDComp() const { +- return mTextureFactoryIdentifier.mCompositorUseDComp; ++ auto lock = mData.Lock(); ++ return lock.ref().mTextureFactoryIdentifier.mCompositorUseDComp; + } + + bool GetUseCompositorWnd() const { +- return mTextureFactoryIdentifier.mUseCompositorWnd; ++ auto lock = mData.Lock(); ++ return lock.ref().mTextureFactoryIdentifier.mUseCompositorWnd; + } + +- const TextureFactoryIdentifier& GetTextureFactoryIdentifier() const { +- return mTextureFactoryIdentifier; ++ TextureFactoryIdentifier GetTextureFactoryIdentifier() const { ++ auto lock = mData.Lock(); ++ return lock.ref().mTextureFactoryIdentifier; + } + + bool DeviceCanReset() const { +@@ -148,8 +165,11 @@ class KnowsCompositor { + } + + protected: +- TextureFactoryIdentifier mTextureFactoryIdentifier; +- RefPtr mSyncObject; ++ struct SharedData { ++ TextureFactoryIdentifier mTextureFactoryIdentifier; ++ RefPtr mSyncObject; ++ }; ++ mutable DataMutex mData; + + const int32_t mSerial; + static mozilla::Atomic sSerialCounter; +diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp +index a2bd49a..c5465f2 100644 +--- a/gfx/layers/ipc/ShadowLayers.cpp ++++ b/gfx/layers/ipc/ShadowLayers.cpp +@@ -144,23 +144,25 @@ struct AutoTxnEnd final { + + void KnowsCompositor::IdentifyTextureHost( + const TextureFactoryIdentifier& aIdentifier) { +- mTextureFactoryIdentifier = aIdentifier; +- +- mSyncObject = ++ auto lock = mData.Lock(); ++ lock.ref().mTextureFactoryIdentifier = aIdentifier; ++ lock.ref().mSyncObject = + SyncObjectClient::CreateSyncObjectClient(aIdentifier.mSyncHandle); + } + +-KnowsCompositor::KnowsCompositor() : mSerial(++sSerialCounter) {} ++KnowsCompositor::KnowsCompositor() ++ : mData("KnowsCompositorMutex"), mSerial(++sSerialCounter) {} + + KnowsCompositor::~KnowsCompositor() = default; + + KnowsCompositorMediaProxy::KnowsCompositorMediaProxy( + const TextureFactoryIdentifier& aIdentifier) { +- mTextureFactoryIdentifier = aIdentifier; ++ auto lock = mData.Lock(); ++ lock.ref().mTextureFactoryIdentifier = aIdentifier; + // overwrite mSerial's value set by the parent class because we use the same + // serial as the KnowsCompositor we are proxying. + mThreadSafeAllocator = ImageBridgeChild::GetSingleton(); +- mSyncObject = mThreadSafeAllocator->GetSyncObject(); ++ lock.ref().mSyncObject = mThreadSafeAllocator->GetSyncObject(); + } + + KnowsCompositorMediaProxy::~KnowsCompositorMediaProxy() = default; +-- +2.27.0 + diff --git a/backport-0002-CVE-2020-35113.patch b/backport-0002-CVE-2020-35113.patch new file mode 100644 index 0000000000000000000000000000000000000000..b2afe79333006c5593c5d997c4a988c5dcb90618 --- /dev/null +++ b/backport-0002-CVE-2020-35113.patch @@ -0,0 +1,233 @@ +From 49bd667c053b2df95264d43b690a6492cdb6296d Mon Sep 17 00:00:00 2001 +From: jcristau +Date: Fri, 25 Feb 2022 09:53:00 +0800 +Subject: [PATCH] 0002-backport-CVE-2020-35113 + +Conflict:NA +Reference:https://hg.mozilla.org/releases/mozilla-esr78/rev/96a892d40be2 +--- + js/src/wasm/WasmInstance.cpp | 91 ++++++++++++++++++++++++++---------- + 1 file changed, 66 insertions(+), 25 deletions(-) + +diff --git a/js/src/wasm/WasmInstance.cpp b/js/src/wasm/WasmInstance.cpp +index 42b28ea..bd4a4ec 100644 +--- a/js/src/wasm/WasmInstance.cpp ++++ b/js/src/wasm/WasmInstance.cpp +@@ -129,57 +129,80 @@ class DebugCodegenVal { + }; + + template +-static bool ToWebAssemblyValue_i32(JSContext* cx, HandleValue val, +- int32_t* loc) { ++static bool ToWebAssemblyValue_i32(JSContext* cx, HandleValue val, int32_t* loc, ++ bool mustWrite64) { + bool ok = ToInt32(cx, val, loc); ++ if (ok && mustWrite64) { ++#if defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64) ++ loc[1] = loc[0] >> 31; ++#else ++ loc[1] = 0; ++#endif ++ } + Debug::print(*loc); + return ok; + } + template +-static bool ToWebAssemblyValue_i64(JSContext* cx, HandleValue val, +- int64_t* loc) { ++static bool ToWebAssemblyValue_i64(JSContext* cx, HandleValue val, int64_t* loc, ++ bool mustWrite64) { ++ MOZ_ASSERT(mustWrite64); + JS_TRY_VAR_OR_RETURN_FALSE(cx, *loc, ToBigInt64(cx, val)); + Debug::print(*loc); + return true; + } + template +-static bool ToWebAssemblyValue_f32(JSContext* cx, HandleValue val, float* loc) { ++static bool ToWebAssemblyValue_f32(JSContext* cx, HandleValue val, float* loc, ++ bool mustWrite64) { + bool ok = RoundFloat32(cx, val, loc); ++ if (ok && mustWrite64) { ++ loc[1] = 0.0; ++ } + Debug::print(*loc); + return ok; + } + template +-static bool ToWebAssemblyValue_f64(JSContext* cx, HandleValue val, +- double* loc) { ++static bool ToWebAssemblyValue_f64(JSContext* cx, HandleValue val, double* loc, ++ bool mustWrite64) { ++ MOZ_ASSERT(mustWrite64); + bool ok = ToNumber(cx, val, loc); + Debug::print(*loc); + return ok; + } + template + static bool ToWebAssemblyValue_anyref(JSContext* cx, HandleValue val, +- void** loc) { ++ void** loc, bool mustWrite64) { + RootedAnyRef result(cx, AnyRef::null()); + if (!BoxAnyRef(cx, val, &result)) { + return false; + } + *loc = result.get().forCompiledCode(); ++#ifndef JS_64BIT ++ if (mustWrite64) { ++ loc[1] = nullptr; ++ } ++#endif + Debug::print(*loc); + return true; + } + template + static bool ToWebAssemblyValue_funcref(JSContext* cx, HandleValue val, +- void** loc) { ++ void** loc, bool mustWrite64) { + RootedFunction fun(cx); + if (!CheckFuncRefValue(cx, val, &fun)) { + return false; + } + *loc = fun; ++#ifndef JS_64BIT ++ if (mustWrite64) { ++ loc[1] = nullptr; ++ } ++#endif + Debug::print(*loc); + return true; + } + template + static bool ToWebAssemblyValue_typeref(JSContext* cx, HandleValue val, +- void** loc) { ++ void** loc, bool mustWrite64) { + JS_ReportErrorNumberUTF8(cx, GetErrorMessage, nullptr, + JSMSG_WASM_TYPEREF_FROM_JS); + return false; +@@ -187,26 +210,29 @@ static bool ToWebAssemblyValue_typeref(JSContext* cx, HandleValue val, + + template + static bool ToWebAssemblyValue(JSContext* cx, HandleValue val, ValType type, +- void* loc) { ++ void* loc, bool mustWrite64) { + switch (type.kind()) { + case ValType::I32: +- return ToWebAssemblyValue_i32(cx, val, (int32_t*)loc); ++ return ToWebAssemblyValue_i32(cx, val, (int32_t*)loc, mustWrite64); + case ValType::I64: +- return ToWebAssemblyValue_i64(cx, val, (int64_t*)loc); ++ return ToWebAssemblyValue_i64(cx, val, (int64_t*)loc, mustWrite64); + case ValType::F32: +- return ToWebAssemblyValue_f32(cx, val, (float*)loc); ++ return ToWebAssemblyValue_f32(cx, val, (float*)loc, mustWrite64); + case ValType::F64: +- return ToWebAssemblyValue_f64(cx, val, (double*)loc); ++ return ToWebAssemblyValue_f64(cx, val, (double*)loc, mustWrite64); + case ValType::V128: + MOZ_CRASH("unexpected v128 in ToWebAssemblyValue"); + case ValType::Ref: + switch (type.refTypeKind()) { + case RefType::Func: +- return ToWebAssemblyValue_funcref(cx, val, (void**)loc); ++ return ToWebAssemblyValue_funcref(cx, val, (void**)loc, ++ mustWrite64); + case RefType::Any: +- return ToWebAssemblyValue_anyref(cx, val, (void**)loc); ++ return ToWebAssemblyValue_anyref(cx, val, (void**)loc, ++ mustWrite64); + case RefType::TypeIndex: +- return ToWebAssemblyValue_typeref(cx, val, (void**)loc); ++ return ToWebAssemblyValue_typeref(cx, val, (void**)loc, ++ mustWrite64); + } + } + MOZ_CRASH("unreachable"); +@@ -353,6 +379,8 @@ static bool UnpackResults(JSContext* cx, const ValTypeVector& resultTypes, + return false; + } + ++ DebugOnly previousOffset = ~(uint64_t)0; ++ + ABIResultIter iter(ResultType::Vector(resultTypes)); + // The values are converted in the order they are pushed on the + // abstract WebAssembly stack; switch to iterate in push order. +@@ -376,8 +404,21 @@ static bool UnpackResults(JSContext* cx, const ValTypeVector& resultTypes, + seenRegisterResult = true; + continue; + } ++ ++ uint32_t result_size = result.size(); ++ MOZ_ASSERT(result_size == 4 || result_size == 8); ++#ifdef DEBUG ++ if (previousOffset == ~(uint64_t)0) { ++ previousOffset = result.stackOffset(); ++ } else { ++ MOZ_ASSERT(previousOffset - (uint64_t)result_size == ++ (uint64_t)result.stackOffset()); ++ previousOffset -= result_size; ++ } ++#endif ++ + char* loc = stackResultsArea.value() + result.stackOffset(); +- if (!ToWebAssemblyValue(cx, rval, result.type(), loc)) { ++ if (!ToWebAssemblyValue(cx, rval, result.type(), loc, result_size == 8)) { + return false; + } + } +@@ -581,7 +622,7 @@ Instance::callImport_i32(Instance* instance, int32_t funcImportIndex, + if (!instance->callImport(cx, funcImportIndex, argc, argv, &rval)) { + return false; + } +- return ToWebAssemblyValue_i32(cx, rval, (int32_t*)argv); ++ return ToWebAssemblyValue_i32(cx, rval, (int32_t*)argv, true); + } + + /* static */ int32_t /* 0 to signal trap; 1 to signal OK */ +@@ -592,7 +633,7 @@ Instance::callImport_i64(Instance* instance, int32_t funcImportIndex, + if (!instance->callImport(cx, funcImportIndex, argc, argv, &rval)) { + return false; + } +- return ToWebAssemblyValue_i64(cx, rval, (int64_t*)argv); ++ return ToWebAssemblyValue_i64(cx, rval, (int64_t*)argv, true); + } + + /* static */ int32_t /* 0 to signal trap; 1 to signal OK */ +@@ -612,7 +653,7 @@ Instance::callImport_f64(Instance* instance, int32_t funcImportIndex, + if (!instance->callImport(cx, funcImportIndex, argc, argv, &rval)) { + return false; + } +- return ToWebAssemblyValue_f64(cx, rval, (double*)argv); ++ return ToWebAssemblyValue_f64(cx, rval, (double*)argv, true); + } + + /* static */ int32_t /* 0 to signal trap; 1 to signal OK */ +@@ -624,7 +665,7 @@ Instance::callImport_anyref(Instance* instance, int32_t funcImportIndex, + return false; + } + static_assert(sizeof(argv[0]) >= sizeof(void*), "fits"); +- return ToWebAssemblyValue_anyref(cx, rval, (void**)argv); ++ return ToWebAssemblyValue_anyref(cx, rval, (void**)argv, true); + } + + /* static */ int32_t /* 0 to signal trap; 1 to signal OK */ +@@ -635,7 +676,7 @@ Instance::callImport_funcref(Instance* instance, int32_t funcImportIndex, + if (!instance->callImport(cx, funcImportIndex, argc, argv, &rval)) { + return false; + } +- return ToWebAssemblyValue_funcref(cx, rval, (void**)argv); ++ return ToWebAssemblyValue_funcref(cx, rval, (void**)argv, true); + } + + /* static */ uint32_t Instance::memoryGrow_i32(Instance* instance, +@@ -2125,7 +2166,7 @@ bool Instance::callExport(JSContext* cx, uint32_t funcIndex, CallArgs args) { + size_t naturalIdx = argTypes.naturalIndex(i); + v = naturalIdx < args.length() ? args[naturalIdx] : UndefinedValue(); + ValType type = funcType->arg(naturalIdx); +- if (!ToWebAssemblyValue(cx, v, type, rawArgLoc)) { ++ if (!ToWebAssemblyValue(cx, v, type, rawArgLoc, true)) { + return false; + } + if (type.isReference()) { +-- +2.27.0 + diff --git a/backport-CVE-2020-26971.patch b/backport-CVE-2020-26971.patch new file mode 100644 index 0000000000000000000000000000000000000000..8dd2ab23881c849fa56b5e7cc258e278511f7608 --- /dev/null +++ b/backport-CVE-2020-26971.patch @@ -0,0 +1,311 @@ +From 2222ae659458bd4ad161aa8e897f3ce7344ca9d0 Mon Sep 17 00:00:00 2001 +From: ryanvm +Date: Thu, 24 Feb 2022 15:03:47 +0800 +Subject: [PATCH] backport-CVE-2020-26971 + +Conflict:NA +Reference:https://hg.mozilla.org/releases/mozilla-esr78/rev/e304cd72b635 +--- + dom/canvas/WebGLFramebuffer.cpp | 123 ++++++++++++++---- + dom/canvas/WebGLTypes.h | 54 +++++++- + .../test/webgl-conf/generated-mochitest.ini | 1 - + .../test/webgl-conf/mochitest-errata.ini | 2 - + 4 files changed, 153 insertions(+), 27 deletions(-) + +diff --git a/dom/canvas/WebGLFramebuffer.cpp b/dom/canvas/WebGLFramebuffer.cpp +index 3357406..7da3ffd 100644 +--- a/dom/canvas/WebGLFramebuffer.cpp ++++ b/dom/canvas/WebGLFramebuffer.cpp +@@ -1260,11 +1260,16 @@ static void GetBackbufferFormats(const WebGLContext* webgl, + } + + /*static*/ +-void WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl, GLint srcX0, +- GLint srcY0, GLint srcX1, GLint srcY1, +- GLint dstX0, GLint dstY0, GLint dstX1, +- GLint dstY1, GLbitfield mask, ++void WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl, GLint _srcX0, ++ GLint _srcY0, GLint _srcX1, GLint _srcY1, ++ GLint _dstX0, GLint _dstY0, GLint _dstX1, ++ GLint _dstY1, GLbitfield mask, + GLenum filter) { ++ auto srcP0 = ivec2{_srcX0, _srcY0}; ++ auto srcP1 = ivec2{_srcX1, _srcY1}; ++ auto dstP0 = ivec2{_dstX0, _dstY0}; ++ auto dstP1 = ivec2{_dstX1, _dstY1}; ++ + const GLbitfield depthAndStencilBits = + LOCAL_GL_DEPTH_BUFFER_BIT | LOCAL_GL_STENCIL_BUFFER_BIT; + if (bool(mask & depthAndStencilBits) && filter == LOCAL_GL_LINEAR) { +@@ -1417,7 +1422,7 @@ void WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl, GLint srcX0, + return; + } + +- if (dstX0 != srcX0 || dstX1 != srcX1 || dstY0 != srcY0 || dstY1 != srcY1) { ++ if (srcP0 != dstP0 || srcP1 != dstP1) { + webgl->ErrorInvalidOperation( + "If the source is multisampled, then the" + " source and dest regions must match exactly."); +@@ -1507,11 +1512,81 @@ void WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl, GLint srcX0, + } + + // - ++ // Mutually constrain src and dst rects for eldritch blits. ++ ++ [&]{ ++ using fvec2 = avec2; // Switch to float, because there's no perfect solution anyway. ++ ++ const auto zero2f = fvec2{0, 0}; ++ const auto srcSizef = AsVec(srcSize).StaticCast(); ++ const auto dstSizef = AsVec(dstSize).StaticCast(); ++ ++ const auto srcP0f = srcP0.StaticCast(); ++ const auto srcP1f = srcP1.StaticCast(); ++ const auto dstP0f = dstP0.StaticCast(); ++ const auto dstP1f = dstP1.StaticCast(); ++ ++ const auto srcRectDiff = srcP1f - srcP0f; ++ const auto dstRectDiff = dstP1f - dstP0f; ++ ++ // Skip if zero-sized. ++ if (!srcRectDiff.x || !srcRectDiff.y || !dstRectDiff.x || !dstRectDiff.y) { ++ srcP0 = srcP1 = dstP0 = dstP1 = {0,0}; ++ return; ++ } ++ ++ // Clamp the rect points ++ const auto srcQ0 = srcP0f.ClampMinMax(zero2f, srcSizef); ++ const auto srcQ1 = srcP1f.ClampMinMax(zero2f, srcSizef); ++ ++ // Normalized to the [0,1] abstact copy rect ++ const auto srcQ0Norm = (srcQ0 - srcP0f) / srcRectDiff; ++ const auto srcQ1Norm = (srcQ1 - srcP0f) / srcRectDiff; ++ ++ // Map into dst ++ const auto srcQ0InDst = dstP0f + srcQ0Norm * dstRectDiff; ++ const auto srcQ1InDst = dstP0f + srcQ1Norm * dstRectDiff; ++ ++ // Clamp the rect points ++ const auto dstQ0 = srcQ0InDst.ClampMinMax(zero2f, dstSizef); ++ const auto dstQ1 = srcQ1InDst.ClampMinMax(zero2f, dstSizef); ++ ++ // Alright, time to go back to src! ++ // Normalized to the [0,1] abstact copy rect ++ const auto dstQ0Norm = (dstQ0 - dstP0f) / dstRectDiff; ++ const auto dstQ1Norm = (dstQ1 - dstP0f) / dstRectDiff; ++ ++ // Map into src ++ const auto dstQ0InSrc = srcP0f + dstQ0Norm * srcRectDiff; ++ const auto dstQ1InSrc = srcP0f + dstQ1Norm * srcRectDiff; ++ ++ const auto srcQ0Constrained = dstQ0InSrc.ClampMinMax(zero2f, srcSizef); ++ const auto srcQ1Constrained = dstQ1InSrc.ClampMinMax(zero2f, srcSizef); ++ ++ // Round, don't floor: ++ srcP0 = (srcQ0Constrained + 0.5).StaticCast(); ++ srcP1 = (srcQ1Constrained + 0.5).StaticCast(); ++ dstP0 = (dstQ0 + 0.5).StaticCast(); ++ dstP1 = (dstQ1 + 0.5).StaticCast(); ++ }(); ++ ++ bool inBounds = true; ++ inBounds &= ( srcP0 == srcP0.Clamp({0,0}, AsVec(srcSize)) ); ++ inBounds &= ( srcP1 == srcP1.Clamp({0,0}, AsVec(srcSize)) ); ++ inBounds &= ( dstP0 == dstP0.Clamp({0,0}, AsVec(dstSize)) ); ++ inBounds &= ( dstP1 == dstP1.Clamp({0,0}, AsVec(dstSize)) ); ++ if (!inBounds) { ++ webgl->ErrorImplementationBug("Subrects still not within src and dst after constraining."); ++ return; ++ } ++ ++ // - ++ // Execute as constrained + + const auto& gl = webgl->gl; + const ScopedDrawCallWrapper wrapper(*webgl); +- gl->fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, +- mask, filter); ++ gl->fBlitFramebuffer(srcP0.x, srcP0.y, srcP1.x, srcP1.y, dstP0.x, dstP0.y, ++ dstP1.x, dstP1.y, mask, filter); + + // - + +@@ -1554,13 +1629,14 @@ void WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl, GLint srcX0, + + if (srcColorFormat->isSRGB) { + // srgb -> linear +- gl->fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, srcX0, srcY0, srcX1, +- srcY1, LOCAL_GL_COLOR_BUFFER_BIT, +- LOCAL_GL_NEAREST); ++ gl->fBlitFramebuffer(srcP0.x, srcP0.y, srcP1.x, srcP1.y, srcP0.x, ++ srcP0.y, srcP1.x, srcP1.y, ++ LOCAL_GL_COLOR_BUFFER_BIT, LOCAL_GL_NEAREST); + } else { + // linear -> srgb +- gl->fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, +- dstY1, LOCAL_GL_COLOR_BUFFER_BIT, filter); ++ gl->fBlitFramebuffer(srcP0.x, srcP0.y, srcP1.x, srcP1.y, dstP0.x, ++ dstP0.y, dstP1.x, dstP1.y, ++ LOCAL_GL_COLOR_BUFFER_BIT, filter); + } + + const auto& blitHelper = *gl->BlitHelper(); +@@ -1574,13 +1650,14 @@ void WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl, GLint srcX0, + + if (srcColorFormat->isSRGB) { + // srgb -> linear +- gl->fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, +- dstY1, LOCAL_GL_COLOR_BUFFER_BIT, filter); ++ gl->fBlitFramebuffer(srcP0.x, srcP0.y, srcP1.x, srcP1.y, dstP0.x, ++ dstP0.y, dstP1.x, dstP1.y, ++ LOCAL_GL_COLOR_BUFFER_BIT, filter); + } else { + // linear -> srgb +- gl->fBlitFramebuffer(dstX0, dstY0, dstX1, dstY1, dstX0, dstY0, dstX1, +- dstY1, LOCAL_GL_COLOR_BUFFER_BIT, +- LOCAL_GL_NEAREST); ++ gl->fBlitFramebuffer(dstP0.x, dstP0.y, dstP1.x, dstP1.y, dstP0.x, ++ dstP0.y, dstP1.x, dstP1.y, ++ LOCAL_GL_COLOR_BUFFER_BIT, LOCAL_GL_NEAREST); + } + } + } +@@ -1595,13 +1672,15 @@ void WebGLFramebuffer::BlitFramebuffer(WebGLContext* webgl, GLint srcX0, + if (webgl->mRasterizerDiscardEnabled) { + gl->fDisable(LOCAL_GL_RASTERIZER_DISCARD); + } +- const WebGLContext::ScissorRect dstRect = { +- std::min(dstX0, dstX1), std::min(dstY0, dstY1), abs(dstX1 - dstX0), +- abs(dstY1 - dstY0)}; ++ ++ const auto dstRectMin = MinExtents(dstP0, dstP1); ++ const auto dstRectMax = MaxExtents(dstP0, dstP1); ++ const auto dstRectSize = dstRectMax - dstRectMin; ++ const WebGLContext::ScissorRect dstRect = {dstRectMin.x, dstRectMin.y, ++ dstRectSize.x, dstRectSize.y}; + dstRect.Apply(*gl); + gl->fClearColor(0, 0, 0, 1); +- +- webgl->DoColorMask(0x8); ++ webgl->DoColorMask(1 << 3); + gl->fClear(LOCAL_GL_COLOR_BUFFER_BIT); + + if (!webgl->mScissorTestEnabled) { +diff --git a/dom/canvas/WebGLTypes.h b/dom/canvas/WebGLTypes.h +index 7aeca93..3244626 100644 +--- a/dom/canvas/WebGLTypes.h ++++ b/dom/canvas/WebGLTypes.h +@@ -15,6 +15,7 @@ + #include "GLDefs.h" + #include "mozilla/Casting.h" + #include "mozilla/CheckedInt.h" ++#include "mozilla/MathAlgorithms.h" + #include "mozilla/Range.h" + #include "mozilla/RefCounted.h" + #include "mozilla/gfx/Point.h" +@@ -391,8 +392,10 @@ struct WebGLContextOptions { + + // - + +-template ++template + struct avec2 { ++ using T = _T; ++ + T x = T(); + T y = T(); + +@@ -418,10 +421,55 @@ struct avec2 { + + bool operator==(const avec2& rhs) const { return x == rhs.x && y == rhs.y; } + bool operator!=(const avec2& rhs) const { return !(*this == rhs); } ++ ++#define _(OP) \ ++ avec2 operator OP(const avec2& rhs) const { \ ++ return {x OP rhs.x, y OP rhs.y}; \ ++ } \ ++ avec2 operator OP(const T rhs) const { return {x OP rhs, y OP rhs}; } ++ ++ _(+) ++ _(-) ++ _(*) ++ _(/) ++ ++#undef _ ++ ++ avec2 Clamp(const avec2& min, const avec2& max) const { ++ return {mozilla::Clamp(x, min.x, max.x), mozilla::Clamp(y, min.y, max.y)}; ++ } ++ ++ // mozilla::Clamp doesn't work on floats, so be clear that this is a min+max ++ // helper. ++ avec2 ClampMinMax(const avec2& min, const avec2& max) const { ++ const auto ClampScalar = [](const T v, const T min, const T max) { ++ return std::max(min, std::min(v, max)); ++ }; ++ return {ClampScalar(x, min.x, max.x), ClampScalar(y, min.y, max.y)}; ++ } ++ ++ template ++ U StaticCast() const { ++ return {static_cast(x), static_cast(y)}; ++ } + }; + +-template ++template ++avec2 MinExtents(const avec2& a, const avec2& b) { ++ return {std::min(a.x, b.x), std::min(a.y, b.y)}; ++} ++ ++template ++avec2 MaxExtents(const avec2& a, const avec2& b) { ++ return {std::max(a.x, b.x), std::max(a.y, b.y)}; ++} ++ ++// - ++ ++template + struct avec3 { ++ using T = _T; ++ + T x = T(); + T y = T(); + T z = T(); +@@ -454,6 +502,8 @@ typedef avec3 ivec3; + typedef avec2 uvec2; + typedef avec3 uvec3; + ++inline ivec2 AsVec(const gfx::IntSize& s) { return {s.width, s.height}; } ++ + // - + + namespace webgl { +diff --git a/dom/canvas/test/webgl-conf/generated-mochitest.ini b/dom/canvas/test/webgl-conf/generated-mochitest.ini +index 0d47a18..5b3da63 100644 +--- a/dom/canvas/test/webgl-conf/generated-mochitest.ini ++++ b/dom/canvas/test/webgl-conf/generated-mochitest.ini +@@ -5174,7 +5174,6 @@ subsuite = webgl2-ext + skip-if = (os == 'win') + [generated/test_2_conformance2__glsl3__matrix-row-major-dynamic-indexing.html] + subsuite = webgl2-ext +-fail-if = (os == 'linux') || (os == 'mac') + [generated/test_2_conformance2__glsl3__matrix-row-major.html] + subsuite = webgl2-ext + [generated/test_2_conformance2__glsl3__misplaced-version-directive.html] +diff --git a/dom/canvas/test/webgl-conf/mochitest-errata.ini b/dom/canvas/test/webgl-conf/mochitest-errata.ini +index 2ef5365..903e721 100644 +--- a/dom/canvas/test/webgl-conf/mochitest-errata.ini ++++ b/dom/canvas/test/webgl-conf/mochitest-errata.ini +@@ -335,8 +335,6 @@ skip-if = (os == 'android') + skip-if = (os == 'win') || (os == 'mac') + [generated/test_2_conformance2__glsl3__tricky-loop-conditions.html] + fail-if = (os == 'win') +-[generated/test_2_conformance2__rendering__blitframebuffer-outside-readbuffer.html] +-fail-if = (os == 'linux') || (os == 'mac') + [generated/test_2_conformance2__textures__misc__tex-srgb-mipmap.html] + fail-if = (os == 'mac') + [generated/test_2_conformance2__textures__video__tex-3d-r11f_g11f_b10f-rgb-float.html] +-- +2.27.0 + diff --git a/backport-CVE-2020-26973.patch b/backport-CVE-2020-26973.patch new file mode 100644 index 0000000000000000000000000000000000000000..55f4cb0b9617b71231986c2b4f66c790ff94e950 --- /dev/null +++ b/backport-CVE-2020-26973.patch @@ -0,0 +1,142 @@ +From ee7ea98ee899d9e7afc02283843df9561a110bd3 Mon Sep 17 00:00:00 2001 +From: ryanvm +Date: Thu, 24 Feb 2022 15:23:26 +0800 +Subject: [PATCH] backport-CVE-2020-26973 + +Conflict:NA +Reference:https://hg.mozilla.org/releases/mozilla-esr78/rev/d4ff6884df02 +--- + servo/components/style/stylesheets/mod.rs | 6 ++-- + .../style/stylesheets/rule_parser.rs | 32 +++++++++---------- + .../style/stylesheets/stylesheet.rs | 5 ++- + 3 files changed, 21 insertions(+), 22 deletions(-) + +diff --git a/servo/components/style/stylesheets/mod.rs b/servo/components/style/stylesheets/mod.rs +index 12ba46b..e814b20 100644 +--- a/servo/components/style/stylesheets/mod.rs ++++ b/servo/components/style/stylesheets/mod.rs +@@ -404,8 +404,10 @@ impl CssRule { + allow_import_rules, + }; + +- parse_one_rule(&mut input, &mut rule_parser) +- .map_err(|_| rule_parser.dom_error.unwrap_or(RulesMutateError::Syntax)) ++ match parse_one_rule(&mut input, &mut rule_parser) { ++ Ok((_, rule)) => Ok(rule), ++ Err(_) => Err(rule_parser.dom_error.unwrap_or(RulesMutateError::Syntax)), ++ } + } + } + +diff --git a/servo/components/style/stylesheets/rule_parser.rs b/servo/components/style/stylesheets/rule_parser.rs +index 74425af..31ae919 100644 +--- a/servo/components/style/stylesheets/rule_parser.rs ++++ b/servo/components/style/stylesheets/rule_parser.rs +@@ -27,7 +27,7 @@ use crate::values::computed::font::FamilyName; + use crate::values::{CssUrl, CustomIdent, KeyframesName}; + use crate::{Namespace, Prefix}; + use cssparser::{AtRuleParser, AtRuleType, Parser, QualifiedRuleParser, RuleListParser}; +-use cssparser::{BasicParseError, BasicParseErrorKind, CowRcStr, SourceLocation}; ++use cssparser::{BasicParseError, BasicParseErrorKind, CowRcStr, SourcePosition, ParserState}; + use selectors::SelectorList; + use servo_arc::Arc; + use style_traits::{ParseError, StyleParseErrorKind}; +@@ -178,7 +178,7 @@ pub enum AtRuleNonBlockPrelude { + impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> { + type PreludeNoBlock = AtRuleNonBlockPrelude; + type PreludeBlock = AtRuleBlockPrelude; +- type AtRule = CssRule; ++ type AtRule = (SourcePosition, CssRule); + type Error = StyleParseErrorKind<'i>; + + fn parse_prelude<'t>( +@@ -253,11 +253,10 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> { + prelude: AtRuleBlockPrelude, + location: SourceLocation, + input: &mut Parser<'i, 't>, +- ) -> Result> { +- AtRuleParser::parse_block(&mut self.nested(), prelude, location, input).map(|rule| { +- self.state = State::Body; +- rule +- }) ++ ) -> Result> { ++ let rule = AtRuleParser::parse_block(&mut self.nested(), prelude, start, input)?; ++ self.state = State::Body; ++ Ok((start.position(), rule)) + } + + #[inline] +@@ -266,7 +265,7 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> { + prelude: AtRuleNonBlockPrelude, + source_location: SourceLocation, + ) -> CssRule { +- match prelude { ++ let rule = match prelude { + AtRuleNonBlockPrelude::Import(url, media) => { + let loader = self + .loader +@@ -299,13 +298,15 @@ impl<'a, 'i> AtRuleParser<'i> for TopLevelRuleParser<'a> { + source_location, + }))) + }, +- } ++ }; ++ ++ (start.position(), rule) + } + } + + impl<'a, 'i> QualifiedRuleParser<'i> for TopLevelRuleParser<'a> { + type Prelude = SelectorList; +- type QualifiedRule = CssRule; ++ type QualifiedRule = (SourcePosition, CssRule); + type Error = StyleParseErrorKind<'i>; + + #[inline] +@@ -326,13 +327,10 @@ impl<'a, 'i> QualifiedRuleParser<'i> for TopLevelRuleParser<'a> { + prelude: Self::Prelude, + location: SourceLocation, + input: &mut Parser<'i, 't>, +- ) -> Result> { +- QualifiedRuleParser::parse_block(&mut self.nested(), prelude, location, input).map( +- |result| { +- self.state = State::Body; +- result +- }, +- ) ++ ) -> Result> { ++ let rule = QualifiedRuleParser::parse_block(&mut self.nested(), prelude, start, input)?; ++ self.state = State::Body; ++ Ok((start.position(), rule)) + } + } + +diff --git a/servo/components/style/stylesheets/stylesheet.rs b/servo/components/style/stylesheets/stylesheet.rs +index 6679f58..81d9dff 100644 +--- a/servo/components/style/stylesheets/stylesheet.rs ++++ b/servo/components/style/stylesheets/stylesheet.rs +@@ -503,19 +503,18 @@ impl Stylesheet { + let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser); + + loop { +- let rule_start = iter.input.position().byte_index(); + let result = match iter.next() { + Some(result) => result, + None => break, + }; + match result { +- Ok(rule) => { ++ Ok((rule_start, rule)) => { + if let Some(ref mut data) = sanitization_data { + if !data.kind.allows(&rule) { + continue; + } + let end = iter.input.position().byte_index(); +- data.output.push_str(&css[rule_start..end]); ++ data.output.push_str(&css[rule_start.byte_index()..end]); + } + // Use a fallible push here, and if it fails, just fall + // out of the loop. This will cause the page to be +-- +2.27.0 + diff --git a/backport-CVE-2020-26974.patch b/backport-CVE-2020-26974.patch new file mode 100644 index 0000000000000000000000000000000000000000..58aa34c84406b4c35a8e92979ebc752ce809a4a6 --- /dev/null +++ b/backport-CVE-2020-26974.patch @@ -0,0 +1,37 @@ +From b094c3903f70c703f4092763beaf7a4b8909f6a1 Mon Sep 17 00:00:00 2001 +From: ryanvm +Date: Fri, 25 Feb 2022 10:02:48 +0800 +Subject: [PATCH] backport-CVE-2020-26974 + +Conflict:NA +Reference:https://hg.mozilla.org/releases/mozilla-esr78/rev/8e6813a535da +--- + layout/generic/nsFrame.cpp | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp +index 257942a..5323ad2 100644 +--- a/layout/generic/nsFrame.cpp ++++ b/layout/generic/nsFrame.cpp +@@ -6167,7 +6167,7 @@ LogicalSize nsIFrame::ComputeSize(gfxContext* aRenderingContext, + mainAxisCoord = &maxContStyleCoord; + // (Note: if our main axis is the block axis, then this 'max-content' + // value will be treated like 'auto', via the IsAutoBSize() call below.) +- } else if (!flexBasis->IsAuto()) { ++ } else if (flexBasis->IsSize() && !flexBasis->IsAuto()) { + // For all other non-'auto' flex-basis values, we just swap in the + // flex-basis itself for the main-size property. + mainAxisCoord = &flexBasis->AsSize(); +@@ -6423,7 +6423,8 @@ LogicalSize nsContainerFrame::ComputeSizeWithIntrinsicDimensions( + // effectively trying to produce the 'auto' sizing behavior). + static const StyleSize autoSize(StyleSize::Auto()); + mainAxisCoord = &autoSize; +- } else if (!flexBasis->IsAuto()) { ++ } else if (flexBasis->IsSize() && !flexBasis->IsAuto()) { ++ + // For all other non-'auto' flex-basis values, we just swap in the + // flex-basis itself for the main-size property. + mainAxisCoord = &flexBasis->AsSize(); +-- +2.27.0 + diff --git a/backport-CVE-2021-29970.patch b/backport-CVE-2021-29970.patch new file mode 100644 index 0000000000000000000000000000000000000000..ecb33f50f0359a279b88d7ed27bd94373fc41715 --- /dev/null +++ b/backport-CVE-2021-29970.patch @@ -0,0 +1,43 @@ +From 686a04e2521dfe06cc9bb50afec156d74d608d0b Mon Sep 17 00:00:00 2001 +From: ryanvm +Date: Fri, 25 Feb 2022 10:07:28 +0800 +Subject: [PATCH] backport-CVE-2021-29970 + +Conflict:NA +Reference:https://hg.mozilla.org/releases/mozilla-esr78/rev/1c6290c3e4e1 +--- + accessible/base/SelectionManager.cpp | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/accessible/base/SelectionManager.cpp b/accessible/base/SelectionManager.cpp +index 5b37cf1..1b1b4eb 100644 +--- a/accessible/base/SelectionManager.cpp ++++ b/accessible/base/SelectionManager.cpp +@@ -101,6 +101,24 @@ void SelectionManager::RemoveDocSelectionListener(PresShell* aPresShell) { + // selection. + Selection* spellSel = frameSel->GetSelection(SelectionType::eSpellCheck); + spellSel->RemoveSelectionListener(this); ++ ++ if (mCurrCtrlNormalSel) { ++ if (mCurrCtrlNormalSel->GetPresShell() == aPresShell) { ++ // Remove 'this' registered as selection listener for the normal selection ++ // if we are removing listeners for its PresShell. ++ mCurrCtrlNormalSel->RemoveSelectionListener(this); ++ mCurrCtrlNormalSel = nullptr; ++ } ++ } ++ ++ if (mCurrCtrlSpellSel) { ++ if (mCurrCtrlSpellSel->GetPresShell() == aPresShell) { ++ // Remove 'this' registered as selection listener for the spellcheck ++ // selection if we are removing listeners for its PresShell. ++ mCurrCtrlSpellSel->RemoveSelectionListener(this); ++ mCurrCtrlSpellSel = nullptr; ++ } ++ } + } + + void SelectionManager::ProcessTextSelChangeEvent(AccEvent* aEvent) { +-- +2.27.0 + diff --git a/mozjs78.spec b/mozjs78.spec index 63b0c40af2ed376afc72b14bf7e9b3353e191e27..95b12efe150027916206e492b1d2efc616f33892 100644 --- a/mozjs78.spec +++ b/mozjs78.spec @@ -2,7 +2,7 @@ Name: mozjs%{major} Version: 78.4.0 -Release: 2 +Release: 3 Summary: SpiderMonkey JavaScript library License: MPLv2.0 and MPLv1.1 and BSD and GPLv2+ and GPLv3+ and LGPLv2+ and AFL and ASL 2.0 URL: https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey @@ -23,6 +23,13 @@ Patch08: spidermonkey_checks_disable.patch Patch09: Update-syn-and-proc-macro2-so-that-Firefox-can-build-on-Rust-nightly-again.patch Patch10: Fix-build-with-rust-nightly.patch +Patch6000: backport-CVE-2020-26971.patch +Patch6001: backport-CVE-2020-26973.patch +Patch6002: backport-0001-CVE-2020-35113.patch +Patch6003: backport-0002-CVE-2020-35113.patch +Patch6004: backport-CVE-2020-26974.patch +Patch6005: backport-CVE-2021-29970.patch + BuildRequires: autoconf213 cargo clang-devel gcc gcc-c++ perl-devel pkgconfig(libffi) pkgconfig(zlib) BuildRequires: python3-devel python3-six readline-devel zip nasm llvm llvm-devel icu rust @@ -101,6 +108,12 @@ popd %doc js/src/README.html %changelog +* Sat Feb 26 2022 wangkerong - 78.4.0-3 +- Type:CVE +- ID:CVE-2020-26971,CVE-2020-26973,CVE-2020-35113,CVE-2020-26974,CVE-2021-29970 +- SUG:NA +- DESC:fix CVE-2020-26971,CVE-2020-26973,CVE-2020-35113,CVE-2020-26974,CVE-2021-29970 + * Tue May 11 2021 zhanzhimin - 78.4.0-2 - Type:bugfix - ID:NA