Firefox · DOM
CVE-2025-49709
Memory Corruption in DOM
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifdom/canvas/TexUnpackBlob.cpp |
modified | |
RecordedCanvasBeginTransactiongfx/layers/RecordedCanvasEventImpl.h |
modified | |
RecordedAddExportSurfacegfx/layers/RecordedCanvasEventImpl.h |
modified | |
mActualSurfacegfx/layers/RecordedCanvasEventImpl.h |
modified | |
ifgfx/layers/RecordedCanvasEventImpl.h |
modified | |
RecordedRemoveExportSurfacegfx/layers/RecordedCanvasEventImpl.h |
modified |
Files Changed
dom/canvas/TexUnpackBlob.cppgfx/2d/2D.hgfx/2d/InlineTranslator.hgfx/layers/RecordedCanvasEventImpl.hgfx/layers/ipc/CanvasChild.cppgfx/layers/ipc/CanvasTranslator.cppgfx/layers/ipc/CanvasTranslator.h
Patch
diff --git a/dom/canvas/TexUnpackBlob.cpp b/dom/canvas/TexUnpackBlob.cpp
index f0c8e11f8d6..815ca11c461 100644
--- a/dom/canvas/TexUnpackBlob.cpp
+++ b/dom/canvas/TexUnpackBlob.cpp
@@ -1040,6 +1040,30 @@ bool TexUnpackSurface::TexOrSubImage(bool isSubImage, bool needsRespec,
gfxCriticalNote << "TexUnpackSurface failed to get CanvasSurface";
return false;
}
+ if (NS_WARN_IF(surf->GetSize().width < GLint(size.x)) ||
+ NS_WARN_IF(surf->GetSize().height < GLint(size.y))) {
+ RefPtr<gfx::DrawTarget> adjusted = gfx::Factory::CreateDrawTarget(
+ gfx::BackendType::SKIA, gfx::IntSize(size.x, size.y),
+ surf->GetFormat());
+ if (!adjusted) {
+ gfxCriticalNote
+ << "Failed to created adjusted target for CanvasSurface";
+ return false;
+ }
+ adjusted->CopySurface(surf, surf->GetRect(), gfx::IntPoint(0, 0));
+ if (RefPtr<gfx::SourceSurface> snapshot = adjusted->Snapshot()) {
+ surf = snapshot->GetDataSurface();
+ if (!surf) {
+ gfxCriticalNote
+ << "Failed to get adjusted snapshot data for CanvasSurface";
+ return false;
+ }
+ } else {
+ gfxCriticalNote
+ << "Failed to create adjusted snapshot for CanvasSurface";
+ return false;
+ }
+ }
} else {
MOZ_ASSERT_UNREACHABLE("Unexpected surface descriptor!");
}
diff --git a/gfx/2d/2D.h b/gfx/2d/2D.h
index 11e44b5dad5..c4161836607 100644
--- a/gfx/2d/2D.h
+++ b/gfx/2d/2D.h
@@ -724,7 +724,7 @@ class SourceSurface : public SupportsThreadSafeWeakPtr<SourceSurface> {
}
/** Tries to generate a SurfaceDescriptor for the surface, if possible. */
- virtual bool GetSurfaceDescriptor(layers::SurfaceDescriptor& aDesc) const {
+ virtual bool GetSurfaceDescriptor(layers::SurfaceDescriptor& aDesc) {
return false;
}
diff --git a/gfx/2d/InlineTranslator.h b/gfx/2d/InlineTranslator.h
index 3e52568b4cc..334edb8404a 100644
--- a/gfx/2d/InlineTranslator.h
+++ b/gfx/2d/InlineTranslator.h
@@ -54,10 +54,6 @@ class InlineTranslator : public Translator {
return result;
}
- bool HasSourceSurface(ReferencePtr aRefPtr) const {
- return mSourceSurfaces.GetWeak(aRefPtr) != nullptr;
- }
-
SourceSurface* LookupSourceSurface(ReferencePtr aRefPtr) final {
SourceSurface* result = mSourceSurfaces.GetWeak(aRefPtr);
MOZ_ASSERT(result);
diff --git a/gfx/layers/RecordedCanvasEventImpl.h b/gfx/layers/RecordedCanvasEventImpl.h
index 40d443b7769..ea3bef03a7f 100644
--- a/gfx/layers/RecordedCanvasEventImpl.h
+++ b/gfx/layers/RecordedCanvasEventImpl.h
@@ -49,7 +49,9 @@ const EventType PRESENT_TEXTURE = EventType(EventType::LAST + 18);
const EventType DEVICE_RESET_ACKNOWLEDGED = EventType(EventType::LAST + 19);
const EventType AWAIT_TRANSLATION_SYNC = EventType(EventType::LAST + 20);
const EventType RESOLVE_EXTERNAL_SNAPSHOT = EventType(EventType::LAST + 21);
-const EventType LAST_CANVAS_EVENT_TYPE = RESOLVE_EXTERNAL_SNAPSHOT;
+const EventType ADD_EXPORT_SURFACE = EventType(EventType::LAST + 22);
+const EventType REMOVE_EXPORT_SURFACE = EventType(EventType::LAST + 23);
+const EventType LAST_CANVAS_EVENT_TYPE = REMOVE_EXPORT_SURFACE;
class RecordedCanvasBeginTransaction final
: public RecordedEventDerived<RecordedCanvasBeginTransaction> {
@@ -874,6 +876,92 @@ RecordedPresentTexture::RecordedPresentTexture(S& aStream)
ReadElement(aStream, mLastRemoteTextureId.mId);
}
+class RecordedAddExportSurface final
+ : public RecordedEventDerived<RecordedAddExportSurface> {
+ public:
+ RecordedAddExportSurface(ReferencePtr aExportID,
+ const RefPtr<gfx::SourceSurface>& aActualSurface)
+ : RecordedEventDerived(ADD_EXPORT_SURFACE),
+ mExportID(aExportID),
+ mActualSurface(aActualSurface) {}
+
+ template <class S>
+ MOZ_IMPLICIT RecordedAddExportSurface(S& aStream);
+
+ bool PlayCanvasEvent(CanvasTranslator* aTranslator) const;
+
+ template <class S>
+ void Record(S& aStream) const;
+
+ std::string GetName() const final { return "RecordedAddExportSurface"; }
+
+ private:
+ ReferencePtr mExportID;
+ ReferencePtr mActualSurface;
+};
+
+inline bool RecordedAddExportSurface::PlayCanvasEvent(
+ CanvasTranslator* aTranslator) const {
+ RefPtr<gfx::SourceSurface> surface =
+ aTranslator->LookupSourceSurface(mActualSurface);
+ if (!surface) {
+ return false;
+ }
+
+ aTranslator->AddExportSurface(mExportID, surface);
+ return true;
+}
+
+template <class S>
+void RecordedAddExportSurface::Record(S& aStream) const {
+ WriteElement(aStream, mExportID);
+ WriteElement(aStream, mActualSurface);
+}
+
+template <class S>
+RecordedAddExportSurface::RecordedAddExportSurface(S& aStream)
+ : RecordedEventDerived(ADD_EXPORT_SURFACE) {
+ ReadElement(aStream, mExportID);
+ ReadElement(aStream, mActualSurface);
+}
+
+class RecordedRemoveExportSurface final
+ : public RecordedEventDerived<RecordedRemoveExportSurface> {
+ public:
+ explicit RecordedRemoveExportSurface(ReferencePtr aExportID)
+ : RecordedEventDerived(REMOVE_EXPORT_SURFACE), mExportID(aExportID) {}
+
+ template <class S>
+ MOZ_IMPLICIT RecordedRemoveExportSurface(S& aStream);
+
+ bool PlayCanvasEvent(CanvasTranslator* aTranslator) const;
+
+ template <class S>
+ void Record(S& aStream) const;
+
+ std::string GetName() const final { return "RecordedRemoveExportSurface"; }
+
+ private:
+ ReferencePtr mExportID;
+};
+
+inline bool RecordedRemoveExportSurface::PlayCanvasEvent(
+ CanvasTranslator* aTranslator) const {
+ aTranslator->RemoveExportSurface(mExportID);
+ return true;
+}
+
+template <class S>
+void RecordedRemoveExportSurface::Record(S& aStream) const {
+ WriteElement(aStream, mExportID);
+}
+
+template <class S>
+RecordedRemoveExportSurface::RecordedRemoveExportSurface(S& aStream)
+ : RecordedEventDerived(REMOVE_EXPORT_SURFACE) {
+ ReadElement(aStream, mExportID);
+}
+
#define FOR_EACH_CANVAS_EVENT(f) \
f(CANVAS_BEGIN_TRANSACTION, RecordedCanvasBeginTransaction); \
f(CANVAS_END_TRANSACTION, RecordedCanvasEndTransaction); \
@@ -896,7 +984,9 @@ RecordedPresentTexture::RecordedPresentTexture(S& aStream)
f(PRESENT_TEXTURE, RecordedPresentTexture); \
f(DEVICE_RESET_ACKNOWLEDGED, RecordedDeviceResetAcknowledged); \
f(AWAIT_TRANSLATION_SYNC, RecordedAwaitTranslationSync); \
- f(RESOLVE_EXTERNAL_SNAPSHOT, RecordedResolveExternalSnapshot);
+ f(RESOLVE_EXTERNAL_SNAPSHOT, RecordedResolveExternalSnapshot); \
+ f(ADD_EXPORT_SURFACE, RecordedAddExportSurface); \
+ f(REMOVE_EXPORT_SURFACE, RecordedRemoveExportSurface);
} // namespace layers
} // namespace mozilla
diff --git a/gfx/layers/ipc/CanvasChild.cpp b/gfx/layers/ipc/CanvasChild.cpp
index c32621ef417..93378de00f5 100644
--- a/gfx/layers/ipc/CanvasChild.cpp
+++ b/gfx/layers/ipc/CanvasChild.cpp
@@ -115,19 +115,21 @@ class SourceSurfaceCanvasRecording final : public gfx::SourceSurface {
~SourceSurfaceCanvasRecording() {
ReferencePtr surfaceAlias = this;
+ ReferencePtr exportID = mExportID;
if (NS_IsMainThread()) {
ReleaseOnMainThread(std::move(mRecorder), surfaceAlias,
- std::move(mRecordedSurface), std::move(mCanvasChild));
+ std::move(mRecordedSurface), std::move(mCanvasChild),
+ exportID);
return;
}
mRecorder->AddPendingDeletion(
Loading diff…
References
On This Page