Firefox · DOM
CVE-2026-117888
Logic Error in DOM
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
mContentIddom/canvas/DrawTargetWebgl.cpp |
modified | |
switchdom/canvas/DrawTargetWebgl.cpp |
modified | |
fordom/canvas/DrawTargetWebgl.cpp |
modified | |
ifdom/canvas/DrawTargetWebgl.cpp |
modified | |
ifgfx/2d/RecordedEventImpl.h |
modified | |
ifgfx/layers/ipc/CanvasTranslator.cpp |
modified | |
GetZeroCopySurfaceFromDMABufgfx/layers/ipc/CanvasTranslator.cpp |
modified |
Files Changed
dom/canvas/DrawTargetWebgl.cppdom/canvas/DrawTargetWebgl.hdom/canvas/DrawTargetWebglInternal.hgfx/2d/RecordedEvent.hgfx/2d/RecordedEventImpl.hgfx/layers/ipc/CanvasTranslator.cppgfx/layers/ipc/CanvasTranslator.h
Patch
diff --git a/dom/canvas/DrawTargetWebgl.cpp b/dom/canvas/DrawTargetWebgl.cpp
index ecd4d069629..4254a2467d4 100644
--- a/dom/canvas/DrawTargetWebgl.cpp
+++ b/dom/canvas/DrawTargetWebgl.cpp
@@ -102,7 +102,8 @@ static const Etagere::AllocatorOptions kR8AllocatorOptions = {16, 1, 1, 0};
#endif
SharedTexture::SharedTexture(const IntSize& aSize, SurfaceFormat aFormat,
- const RefPtr<WebGLTexture>& aTexture)
+ const RefPtr<WebGLTexture>& aTexture,
+ const dom::ContentParentId& aContentId)
: BackingTexture(aSize, aFormat, aTexture),
mAtlasAllocator(
#ifdef XP_WIN
@@ -111,7 +112,8 @@ SharedTexture::SharedTexture(const IntSize& aSize, SurfaceFormat aFormat,
aSize.width, aSize.height, &kR8AllocatorOptions)
:
#endif
- Etagere::etagere_atlas_allocator_new(aSize.width, aSize.height)) {
+ Etagere::etagere_atlas_allocator_new(aSize.width, aSize.height)),
+ mContentId(aContentId) {
}
SharedTexture::~SharedTexture() {
@@ -432,7 +434,8 @@ void SharedContextWebgl::ClearCachesIfNecessary() {
// Try to initialize a new WebGL context. Verifies that the requested size does
// not exceed the available texture limits and that shader creation succeeded.
bool DrawTargetWebgl::Init(const IntSize& size, const SurfaceFormat format,
- const RefPtr<SharedContextWebgl>& aSharedContext) {
+ const RefPtr<SharedContextWebgl>& aSharedContext,
+ const dom::ContentParentId& aContentId) {
switch (format) {
case SurfaceFormat::B8G8R8A8:
case SurfaceFormat::B8G8R8X8:
@@ -454,6 +457,8 @@ bool DrawTargetWebgl::Init(const IntSize& size, const SurfaceFormat format,
mSharedContext->mDrawTargetCount++;
gReportedTargetCount++;
+ mContentId = aContentId;
+
if (size_t(std::max(size.width, size.height)) >
mSharedContext->mMaxTextureSize) {
return false;
@@ -1060,14 +1065,15 @@ bool DrawTargetWebgl::CanCreate(const IntSize& aSize, SurfaceFormat aFormat) {
already_AddRefed<DrawTargetWebgl> DrawTargetWebgl::Create(
const IntSize& aSize, SurfaceFormat aFormat,
- const RefPtr<SharedContextWebgl>& aSharedContext) {
+ const RefPtr<SharedContextWebgl>& aSharedContext,
+ const dom::ContentParentId& aContentId) {
// Validate the size and format.
if (!CanCreate(aSize, aFormat)) {
return nullptr;
}
RefPtr<DrawTargetWebgl> dt = new DrawTargetWebgl;
- if (!dt->Init(aSize, aFormat, aSharedContext) || !dt->IsValid()) {
+ if (!dt->Init(aSize, aFormat, aSharedContext, aContentId) || !dt->IsValid()) {
return nullptr;
}
@@ -2855,8 +2861,8 @@ void SharedContextWebgl::BindScratchFramebuffer(TextureHandle* aHandle,
// Allocate a new texture handle backed by either a standalone texture or as a
// sub-texture of a larger shared texture.
already_AddRefed<TextureHandle> SharedContextWebgl::AllocateTextureHandle(
- SurfaceFormat aFormat, const IntSize& aSize, bool aAllowShared,
- bool aRenderable, const WebGLTexture* aAvoid) {
+ DrawTargetWebgl* aDT, SurfaceFormat aFormat, const IntSize& aSize,
+ bool aAllowShared, bool aRenderable, const WebGLTexture* aAvoid) {
// Don't allow allocating textures bigger than the reported limit.
if (size_t(std::max(aSize.width, aSize.height)) > mMaxTextureSize) {
return nullptr;
@@ -2870,13 +2876,17 @@ already_AddRefed<TextureHandle> SharedContextWebgl::AllocateTextureHandle(
// The requested page size for shared textures.
int32_t pageSize = int32_t(std::min(
StaticPrefs::gfx_canvas_accelerated_shared_page_size(), mMaxTextureSize));
- if (aAllowShared && std::max(aSize.width, aSize.height) <= pageSize / 2) {
+ if (aAllowShared && aDT &&
+ std::max(aSize.width, aSize.height) <= pageSize / 2) {
// Ensure that the surface is no bigger than a quadrant of a shared texture
// page. If so, try to allocate it to a shared texture. Look for any
- // existing shared texture page with a matching format and allocate
- // from that if possible.
+ // existing shared texture page with a matching format and allocate from
+ // that if possible. Restrict allocation to pages that only match the
+ // target's content id.
+ const dom::ContentParentId& contentId = aDT->GetContentId();
for (auto& shared : mSharedTextures) {
- if (shared->GetFormat() == aFormat &&
+ if (shared->GetContentId() == contentId &&
+ shared->GetFormat() == aFormat &&
shared->IsRenderable() == aRenderable &&
shared->GetWebGLTexture() != aAvoid) {
bool wasEmpty = !shared->HasAllocatedHandles();
@@ -2895,8 +2905,8 @@ already_AddRefed<TextureHandle> SharedContextWebgl::AllocateTextureHandle(
// format, then allocate a new page to put the request in.
if (!handle) {
if (RefPtr<WebGLTexture> tex = mWebgl->CreateTexture()) {
- RefPtr<SharedTexture> shared =
- new SharedTexture(IntSize(pageSize, pageSize), aFormat, tex);
+ RefPtr<SharedTexture> shared = new SharedTexture(
+ IntSize(pageSize, pageSize), aFormat, tex, contentId);
if (aRenderable) {
shared->MarkRenderable();
}
@@ -3346,7 +3356,7 @@ bool SharedContextWebgl::DrawRectAccel(
// surface size may change via a forced update, then don't allocate
// from a shared texture page.
handle = AllocateTextureHandle(
- format, texSize,
+ mCurrentTarget, format, texSize,
!aForceUpdate && surfacePattern.mExtendMode == ExtendMode::CLAMP);
if (!handle) {
MOZ_ASSERT(false);
@@ -3579,7 +3589,7 @@ already_AddRefed<WebGLTexture> SharedContextWebgl::GetFilterInputTexture(
// There is no existing handle. Try to allocate a new one. If the
// surface size may change via a forced update, then don't allocate
// from a shared texture page.
- handle = AllocateTextureHandle(format, texSize);
+ handle = AllocateTextureHandle(mCurrentTarget, format, texSize);
if (!handle) {
MOZ_ASSERT(false);
return nullptr;
@@ -3645,8 +3655,8 @@ bool SharedContextWebgl::FilterRect(const Rect& aDestRect,
// If sourcing from a texture handle as input, be careful not to render to
// a handle with the same exact backing texture, which is not allowed in
// WebGL.
- RefPtr<TextureHandle> targetHandle =
- AllocateTextureHandle(format, targetSize, true, true, tex);
+ RefPtr<TextureHandle> targetHandle = AllocateTextureHandle(
+ mCurrentTarget, format, targetSize, true, true, tex);
if (!targetHandle) {
MOZ_ASSERT(false);
return false;
@@ -3837,7 +3847,8 @@ bool SharedContextWebgl::BlurRectPass(
// a handle with the same exact backing texture, which is not allowed in
// WebGL.
RefPtr<TextureHandle> targetHandle = AllocateTextureHandle(
- aFilter ? format : SurfaceFormat::A8, targetSize, true, true, tex);
+ mCurrentTarget, aFilter ? format : SurfaceFormat::A8, targetSize, true,
+ true, tex);
if (!targetHandle) {
MOZ_ASSERT(false);
return false;
@@ -4022,7 +4033,7 @@ already_AddRefed<SourceSurface> SharedContextWebgl::DownscaleBlurInput(
IntSize halfSize = (sourceRect.Size() + IntSize(1, 1)) / 2;
// Allocate a half-size texture for the downscale target.
RefPtr<TextureHandle> halfHandle = AllocateTextureHandle(
- aSurface->GetFormat(), halfSize, true, true, fullTex);
+ mCurrentTarget, aSurface->GetFormat(), halfSize, true, true, fullTex);
if (!halfHandle) {
break;
}
@@ -4232,7 +4243,7 @@ already_AddRefed<TextureHandle> SharedContextWebgl::ResolveFilterInputAccel(
RoundToFactor(aSourceRect.height, roundFactor))
: aSourceRect.Size();
RefPtr<TextureHandle> handle =
- AllocateTextureHandle(aFormat, roundSize, true, true);
+ AllocateTextureHandle(aDT, aFormat, roundSize, true, true);
if (!handle) {
return nullptr;
}
@@ -5014,8 +5025,8 @@ static inline AAStrokeMode SupportsAAStroke(const Pattern& aPattern,
already_AddRefed<TextureHandle> SharedContextWebgl::DrawStrokeMask(
const PathVertexRange& aVertexRange, const IntSize& aSize) {
// Allocate a new texture handle to store the rendered mask.
- RefPtr<TextureHandle> handle =
- AllocateTextureHandle(SurfaceFormat::A8, aSize, true, true);
+ RefPtr<TextureHandle> handle = AllocateTextureHandle(
+ mCurrentTarget, SurfaceFormat::A8, aSize, true, true);
if (!handle) {
return nullptr;
}
@@ -6725,14 +6736,14 @@ std::shared_ptr<gl::SharedSurface> SharedContextWebgl::ExportSharedSurface(
}
already_AddRefed<SourceSurface> SharedContextWebgl::ImportSurfaceDescriptor(
- const layers::SurfaceDescriptor& aDesc, const IntSize& aSize,
- SurfaceFormat aFormat) {
+ DrawTargetWebgl* aDT, const layers::SurfaceDescriptor& aDesc,
+ const IntSize& aSize, SurfaceFormat aFormat) {
if (IsContextLost()) {
return nullptr;
}
RefPtr<TextureHandle> handle =
- AllocateTextureHandle(aFormat, aSize, true, true);
+ AllocateTextureHandle(aDT, aFormat, aSize, true, true);
if (!handle) {
return nullptr;
}
@@ -6775,7 +6786,7 @@ already_AddRefed<SourceSurface> SharedContextWebgl::ImportSurfaceDescriptor(
already_AddRefed<SourceSurface> DrawTargetWebgl::ImportSurfaceDescriptor(
const layers::SurfaceDescriptor& aDesc, const IntSize& aSize,
SurfaceFormat aFormat) {
- return mSharedContext->ImportSurfaceDescriptor(aDesc, aSize, aFormat);
+ return mSharedContext->ImportSurfaceDescriptor(this, aDesc, aSize, aFormat);
}
already_AddRefed<DrawTarget> DrawTargetWebgl::CreateSimilarDrawTarget(
diff --git a/dom/canvas/DrawTargetWebgl.h b/dom/canvas/DrawTargetWebgl.h
index e63da448eb3..cc980c44ac0 100644
--- a/dom/canvas/DrawTargetWebgl.h
+++ b/dom/canvas/DrawTargetWebgl.h
@@ -13,6 +13,7 @@
#include "mozilla/Array.h"
#include "mozilla/LinkedList.h"
#include "mozilla/WeakPtr.h"
+#include "mozilla/dom/ipc/IdType.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/gfx/PathSkia.h"
#include "mozilla/ipc/SharedMemoryHandle.h"
@@ -104,8 +105,8 @@ class SharedContextWebgl : public mozilla::RefCounted<SharedContextWebgl>,
layers::TextureType aTextureType, SourceSurface* aSurface);
already_AddRefed<SourceSurface> ImportSurfaceDescriptor(
- const layers::SurfaceDescriptor& aDesc, const gfx::IntSize& aSize,
- SurfaceFormat aFormat);
+ DrawTargetWebgl* aDT, const layers::SurfaceDescriptor& aDesc,
+ const gfx::IntSize& aSize, SurfaceFormat aFormat);
private:
SharedContextWebgl();
@@ -390,8 +391,9 @@ class SharedContextWebgl : public mozilla::RefCounted<SharedContextWebgl>,
void BindScratchFramebuffer(TextureHandle* aHandle, bool aInit,
const IntSize& aViewportSize = IntSize());
already_AddRefed<TextureHandle> AllocateTextureHandle(
- SurfaceFormat aFormat, const IntSize& aSize, bool aAllowShared = true,
- bool aRenderable = false, const WebGLTexture* aAvoid = nullptr);
+ DrawTargetWebgl* aDT, SurfaceFormat aFormat, const IntSize& aSize,
+ bool aAllowShared = true, bool aRenderable = false,
+ const WebGLTexture* aAvoid = nullptr);
void DrawQuad();
void DrawTriangles(const PathVertexRange& aRange);
bool DrawRectAccel(const Rect& aRect, const Pattern& aPattern,
@@ -601,6 +603,7 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
UsageProfile mProfile;
RefPtr<SharedContextWebgl> mSharedContext;
+ dom::ContentParentId mContentId;
public:
DrawTargetWebgl();
@@ -609,10 +612,12 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
static bool CanCreate(const IntSize& aSize, SurfaceFormat aFormat);
static already_AddRefed<DrawTargetWebgl> Create(
const IntSize& aSize, SurfaceFormat aFormat,
- const RefPtr<SharedContextWebgl>& aSharedContext);
+ const RefPtr<SharedContextWebgl>& aSharedContext,
+ const dom::ContentParentId& aContentId);
bool Init(const IntSize& aSize, SurfaceFormat aFormat,
- const RefPtr<SharedContextWebgl>& aSharedContext);
+ const RefPtr<SharedContextWebgl>& aSharedContext,
+ const dom::ContentParentId& aContentId);
bool IsValid() const override;
@@ -625,6 +630,7 @@ class DrawTargetWebgl : public DrawTarget, public SupportsWeakPtr {
const RefPtr<SharedContextWebgl>& GetSharedContext() const {
return mSharedContext;
}
+ const dom::ContentParentId& GetContentId() const { return mContentId; }
bool HasDataSnapshot() const;
bool EnsureDataSnapshot();
diff --git a/dom/canvas/DrawTargetWebglInternal.h b/dom/canvas/DrawTargetWebglInternal.h
index dda9b25b9bf..ed72c54cd84 100644
--- a/dom/canvas/DrawTargetWebglInternal.h
+++ b/dom/canvas/DrawTargetWebglInternal.h
@@ -220,7 +220,8 @@ class SharedTexture : public RefCounted<SharedTexture>, public BackingTexture {
MOZ_DECLARE_REFCOUNTED_TYPENAME(SharedTexture)
SharedTexture(const IntSize& aSize, SurfaceFormat aFormat,
- const RefPtr<WebGLTexture>& aTexture);
+ const RefPtr<WebGLTexture>& aTexture,
+ const dom::ContentParentId& aContentId);
~SharedTexture();
already_AddRefed<SharedTextureHandle> Allocate(const IntSize& aSize);
@@ -231,8 +232,11 @@ class SharedTexture : public RefCounted<SharedTexture>, public BackingTexture {
mAtlasAllocator) > 0;
}
+ const dom::ContentParentId& GetContentId() const { return mContentId; }
+
private:
Etagere::AtlasAllocator* mAtlasAllocator = nullptr;
+ dom::ContentParentId mContentId;
};
// SharedTextureHandle is an allocated region within a large SharedTexture page
diff --git a/gfx/2d/RecordedEvent.h b/gfx/2d/RecordedEvent.h
index b3049d86f8d..a3a81b300c7 100644
--- a/gfx/2d/RecordedEvent.h
+++ b/gfx/2d/RecordedEvent.h
@@ -109,7 +109,7 @@ class Translator {
}
virtual already_AddRefed<SourceSurface>
LookupSourceSurfaceFromSurfaceDescriptor(
- const layers::SurfaceDescriptor& aDesc) {
+ DrawTarget* aDT, const layers::SurfaceDescriptor& aDesc) {
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return nullptr;
}
diff --git a/gfx/2d/RecordedEventImpl.h b/gfx/2d/RecordedEventImpl.h
index 6ba0fb68575..88ec520156f 100644
--- a/gfx/2d/RecordedEventImpl.h
+++ b/gfx/2d/RecordedEventImpl.h
@@ -3297,7 +3297,7 @@ inline bool RecordedDrawSurfaceDescriptor::PlayEvent(
}
RefPtr<SourceSurface> surface =
- aTranslator->LookupSourceSurfaceFromSurfaceDescriptor(mDesc);
+ aTranslator->LookupSourceSurfaceFromSurfaceDescriptor(dt, mDesc);
if (!surface) {
return false;
}
diff --git a/gfx/layers/ipc/CanvasTranslator.cpp b/gfx/layers/ipc/CanvasTranslator.cpp
index befffefb5c5..2c1b6d6718c 100644
--- a/gfx/layers/ipc/CanvasTranslator.cpp
+++ b/gfx/layers/ipc/CanvasTranslator.cpp
@@ -1243,8 +1243,8 @@ already_AddRefed<gfx::DrawTarget> CanvasTranslator::CreateDrawTarget(
if (EnsureSharedContextWebgl()) {
mSharedContext->EnterTlsScope();
}
- if (RefPtr<gfx::DrawTargetWebgl> webgl =
- gfx::DrawTargetWebgl::Create(aSize, aFormat, mSharedContext)) {
+ if (RefPtr<gfx::DrawTargetWebgl> webgl = gfx::DrawTargetWebgl::Create(
+ aSize, aFormat, mSharedContext, mContentId)) {
webgl->BeginFrame(true);
dt = webgl.forget().downcast<gfx::DrawTarget>();
if (dt) {
@@ -1637,7 +1637,8 @@ CanvasTranslator::MaybeRecycleDataSurfaceForSurfaceDescriptor(
#ifdef MOZ_WIDGET_GTK
already_AddRefed<gfx::SourceSurface>
-CanvasTranslator::GetZeroCopySurfaceFromDMABuf(TextureHost* aTextureHost) {
+CanvasTranslator::GetZeroCopySurfaceFromDMABuf(gfx::DrawTarget* aDT,
+ TextureHost* aTextureHost) {
if (!aTextureHost) {
return nullptr;
}
@@ -1672,16 +1673,17 @@ CanvasTranslator::GetZeroCopySurfaceFromDMABuf(TextureHost* aTextureHost) {
default:
return nullptr;
}
- if (!EnsureSharedContextWebgl() || !mSharedContext) {
- return nullptr;
+ if (aDT->GetBackendType() == gfx::BackendType::WEBGL) {
+ return static_cast<gfx::DrawTargetWebgl*>(aDT)->ImportSurfaceDescriptor(
+ hostSd, size, format);
}
- return mSharedContext->ImportSurfaceDescriptor(hostSd, size, format);
+ return nullptr;
}
#endif
already_AddRefed<gfx::SourceSurface>
CanvasTranslator::LookupSourceSurfaceFromSurfaceDescriptor(
- const SurfaceDescriptor& aDesc) {
+ DrawTarget* aDT, const SurfaceDescriptor& aDesc) {
if (!SDIsSupportedRemoteDecoder(aDesc)) {
return nullptr;
}
@@ -1749,7 +1751,7 @@ CanvasTranslator::LookupSourceSurfaceFromSurfaceDescriptor(
#ifdef MOZ_WIDGET_GTK
if (sdrd.videoType() == RemoteDecoderVideoType::DMABuf) {
if (RefPtr<gfx::SourceSurface> surf =
- GetZeroCopySurfaceFromDMABuf(texture)) {
+ GetZeroCopySurfaceFromDMABuf(aDT, texture)) {
return surf.forget();
}
// The zero-copy import can fail for an unsupported layout or a lost shared
@@ -1891,7 +1893,7 @@ bool CanvasTranslator::ResolveExternalSnapshot(uint64_t aSyncId,
// If we can't import the surface using the DT, then try using the
// global shared context to allow for a readback.
resolved = mSharedContext->ImportSurfaceDescriptor(
- *snapshot.mDescriptor, aSize, aFormat);
+ nullptr, *snapshot.mDescriptor, aSize, aFormat);
}
}
snapshot.mSharedSurface->EndRead();
diff --git a/gfx/layers/ipc/CanvasTranslator.h b/gfx/layers/ipc/CanvasTranslator.h
index 09d9325d112..2b783e782e2 100644
--- a/gfx/layers/ipc/CanvasTranslator.h
+++ b/gfx/layers/ipc/CanvasTranslator.h
@@ -253,7 +253,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
uint64_t aKey) final;
already_AddRefed<gfx::SourceSurface> LookupSourceSurfaceFromSurfaceDescriptor(
- const SurfaceDescriptor& aDesc) final;
+ gfx::DrawTarget* aDT, const SurfaceDescriptor& aDesc) final;
/**
* Gets the cached DataSourceSurface, if it exists, associated with a
@@ -479,7 +479,7 @@ class CanvasTranslator final : public gfx::InlineTranslator,
// on the GPU, returning a directly samplable surface (no CPU download).
// Falls back to nullptr when GL import is unavailable.
already_AddRefed<gfx::SourceSurface> GetZeroCopySurfaceFromDMABuf(
... (file diff truncated)
Loading diff…
References
On This Page