Firefox · Graphics
CVE-2026-100784
Logic Error in Graphics
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifgfx/thebes/gfxDWriteFontList.cpp |
modified |
Files Changed
gfx/thebes/gfxDWriteFontList.cppgfx/thebes/gfxDWriteFontList.hgfx/thebes/gfxFontEntry.h
Patch
diff --git a/gfx/thebes/gfxDWriteFontList.cpp b/gfx/thebes/gfxDWriteFontList.cpp
index ed6761af2d8..e0ebe5b998e 100644
--- a/gfx/thebes/gfxDWriteFontList.cpp
+++ b/gfx/thebes/gfxDWriteFontList.cpp
@@ -500,10 +500,15 @@ static void DestroyBlobFunc(void* aUserData) {
}
hb_blob_t* gfxDWriteFontEntry::GetFontTableInternal(uint32_t aTag) {
- // try to avoid potentially expensive DWrite call if we haven't actually
+ // Try to avoid potentially expensive DWrite call if we haven't actually
// created the font face yet, by using the gfxFontEntry method that will
- // use CopyFontTable and then cache the data
- if (!mFontFace) {
+ // use CopyFontTable and then cache the data.
+ RefPtr<IDWriteFontFace> fontFace;
+ {
+ AutoReadLock lock(mLock);
+ fontFace = mFontFace;
+ }
+ if (!fontFace) {
return gfxFontEntry::GetFontTableInternal(aTag);
}
@@ -511,10 +516,10 @@ hb_blob_t* gfxDWriteFontEntry::GetFontTableInternal(uint32_t aTag) {
UINT32 size;
void* context;
BOOL exists;
- HRESULT hr = mFontFace->TryGetFontTable(NativeEndian::swapToBigEndian(aTag),
- &data, &size, &context, &exists);
+ HRESULT hr = fontFace->TryGetFontTable(NativeEndian::swapToBigEndian(aTag),
+ &data, &size, &context, &exists);
if (SUCCEEDED(hr) && exists) {
- FontTableRec* ftr = new FontTableRec(mFontFace, context);
+ FontTableRec* ftr = new FontTableRec(fontFace, context);
return hb_blob_create(static_cast<const char*>(data), size,
HB_MEMORY_MODE_READONLY, ftr, DestroyBlobFunc);
}
@@ -621,17 +626,26 @@ bool gfxDWriteFontEntry::HasVariationsInternal() {
return mHasVariations;
}
- if (!mFontFace) {
- // CreateFontFace will initialize the mFontFace field, and also
- // mFontFace5 if available on the current DWrite version.
- RefPtr<IDWriteFontFace> fontFace;
- if (NS_FAILED(CreateFontFace(getter_AddRefs(fontFace)))) {
+ {
+ AutoReadLock lock(mLock);
+ if (mFontFace) {
+ if (mFontFace5) {
+ mHasVariations = mFontFace5->HasVariations();
+ }
return mHasVariations;
}
}
- if (mFontFace5) {
- mHasVariations = mFontFace5->HasVariations();
+
+ // CreateFontFace will initialize the mFontFace field, and also
+ // mFontFace5 if available on the current DWrite version.
+ RefPtr<IDWriteFontFace> fontFace;
+ if (NS_SUCCEEDED(CreateFontFace(getter_AddRefs(fontFace)))) {
+ AutoReadLock lock(mLock);
+ if (mFontFace5) {
+ mHasVariations = mFontFace5->HasVariations();
+ }
}
+
return mHasVariations;
}
@@ -643,9 +657,12 @@ void gfxDWriteFontEntry::GetVariationAxesInternal(
// HasVariations() will have ensured the mFontFace5 interface is available;
// so we can get an IDWriteFontResource and ask it for the axis info.
RefPtr<IDWriteFontResource> resource;
- HRESULT hr = mFontFace5->GetFontResource(getter_AddRefs(resource));
- if (FAILED(hr) || !resource) {
- return;
+ {
+ AutoReadLock lock(mLock);
+ HRESULT hr = mFontFace5->GetFontResource(getter_AddRefs(resource));
+ if (FAILED(hr) || !resource) {
+ return;
+ }
}
uint32_t count = resource->GetFontAxisCount();
@@ -690,7 +707,11 @@ void gfxDWriteFontEntry::GetVariationInstancesInternal(
#if MOZ_FONTATIONS
void gfxDWriteFontEntry::InitSkrifaFontFace() {
- RefPtr<IDWriteFontFace> face = mFontFace;
+ RefPtr<IDWriteFontFace> face;
+ {
+ AutoReadLock lock(mLock);
+ face = mFontFace;
+ }
if (!face) {
if (!mFont || FAILED(mFont->CreateFontFace(getter_AddRefs(face)))) {
return;
@@ -846,6 +867,11 @@ nsresult gfxDWriteFontEntry::CreateFontFace(
(aTag >> 8) & 0xff, aTag & 0xff);
};
+ // Must read this *before* taking the write lock.
+ bool hasVariations = HasVariations();
+
+ AutoWriteLock lock(mLock);
+
MOZ_SEH_TRY {
// initialize mFontFace if this hasn't been done before
if (!mFontFace) {
@@ -896,7 +922,7 @@ nsresult gfxDWriteFontEntry::CreateFontFace(
// If the IDWriteFontFace5 interface is available, we can try using
// IDWriteFontResource to create a new modified face.
- if (mFontFace5 && (HasVariations() || needSimulations)) {
+ if (mFontFace5 && (hasVariations || needSimulations)) {
RefPtr<IDWriteFontResource> resource;
HRESULT hr = mFontFace5->GetFontResource(getter_AddRefs(resource));
if (SUCCEEDED(hr) && resource) {
diff --git a/gfx/thebes/gfxDWriteFontList.h b/gfx/thebes/gfxDWriteFontList.h
index 9d50c2a3227..5f36003dadb 100644
--- a/gfx/thebes/gfxDWriteFontList.h
+++ b/gfx/thebes/gfxDWriteFontList.h
@@ -235,9 +235,9 @@ class gfxDWriteFontEntry final : public gfxFontEntry {
// font face corresponding to the mFont/mFontFile *without* any DWrite
// style simulations applied
- RefPtr<IDWriteFontFace> mFontFace;
+ RefPtr<IDWriteFontFace> mFontFace MOZ_GUARDED_BY(mLock);
// Extended fontface interface if supported, else null
- RefPtr<IDWriteFontFace5> mFontFace5;
+ RefPtr<IDWriteFontFace5> mFontFace5 MOZ_GUARDED_BY(mLock);
DWRITE_FONT_FACE_TYPE mFaceType;
diff --git a/gfx/thebes/gfxFontEntry.h b/gfx/thebes/gfxFontEntry.h
index 05f74f34b92..74c9556c87b 100644
--- a/gfx/thebes/gfxFontEntry.h
+++ b/gfx/thebes/gfxFontEntry.h
@@ -522,16 +522,16 @@ class gfxFontEntry {
* Font-variation query methods. These will call through to ...Internal()
* implementation methods if we don't have a Skrifa font to query.
*/
- bool HasVariations();
+ bool HasVariations() MOZ_EXCLUDES(mLock);
void GetVariationAxes(nsTArray<gfxFontVariationAxis>& aVariationAxes);
void GetVariationInstances(nsTArray<gfxFontVariationInstance>& aInstances);
- bool HasBoldVariableWeight();
- bool HasItalicVariation();
- bool HasSlantVariation();
- bool HasOpticalSize();
+ bool HasBoldVariableWeight() MOZ_EXCLUDES(mLock);
+ bool HasItalicVariation() MOZ_EXCLUDES(mLock);
+ bool HasSlantVariation() MOZ_EXCLUDES(mLock);
+ bool HasOpticalSize() MOZ_EXCLUDES(mLock);
- void CheckForVariationAxes();
+ void CheckForVariationAxes() MOZ_EXCLUDES(mLock);
// Set up the entry's weight/width/style ranges according to axes found
// by GetVariationAxes (for installed fonts; do NOT call this for user
@@ -797,7 +797,7 @@ class gfxFontEntry {
// Caller is responsible to call hb_blob_destroy() on the returned blob
// (if non-nullptr) when no longer required. For transient access to a
// table, use of AutoTable (below) is generally preferred.
- virtual hb_blob_t* GetFontTableInternal(uint32_t aTag);
+ virtual hb_blob_t* GetFontTableInternal(uint32_t aTag) MOZ_EXCLUDES(mLock);
// Check for presence of a given table.
virtual bool HasFontTableInternal(uint32_t aTableTag);
Loading diff…
References
On This Page