Closed Bug 2079768 Opened 10 days ago Closed 7 days ago

Crash in [@ gfxFontSrcURI::GetSpecOrDefault]

Categories

(Core :: Layout: Text and Fonts, defect)

defect

Tracking

()

RESOLVED FIXED
160 Branch
Tracking Status
firefox-esr153 --- wontfix
firefox158 --- wontfix
firefox159 --- wontfix
firefox160 --- fixed

People

(Reporter: clouseau-bot, Assigned: dholbert)

References

(Blocks 1 open bug)

Details

(Keywords: crash)

Crash Data

Attachments

(2 files)

Crash report: https://crash-stats.mozilla.org/report/index/32702c94-a62a-4ffa-a0bb-4e50b0261008

Crash Reason:

EXCEPTION_ACCESS_VIOLATION_READ at 0x0000000000000000

Top 10 frames:

0  xul.dll  gfxFontSrcURI::GetSpecOrDefault()  gfx/thebes/gfxFontSrcURI.cpp:107
1  xul.dll  gfxUserFontEntry::LoadPlatformFont(unsigned int, unsigned char const*&&, unsigne...  gfx/thebes/gfxUserFontSet.cpp:844
2  xul.dll  gfxUserFontEntry::LoadPlatformFontSync(unsigned int, unsigned char const*&&, uns...  gfx/thebes/gfxUserFontSet.cpp:695
3  xul.dll  gfxUserFontEntry::DoLoadNextSrc(bool)  gfx/thebes/gfxUserFontSet.cpp:641
4  xul.dll  mozilla::dom::FontFace::Constructor(mozilla::dom::GlobalObject const&, nsTSubstr...  layout/style/FontFace.cpp:143
5  xul.dll  mozilla::dom::FontFace_Binding::_constructor(JSContext*, unsigned int, JS::Value...  dom/bindings/FontFaceBinding.cpp:2132
6  xul.dll  InternalConstruct(JSContext*, js::AnyConstructArgs const&, js::CallReason)  js/src/vm/Interpreter.cpp:754
7  xul.dll  js::jit::DoCallFallback(JSContext*, js::jit::BaselineFrame*, js::jit::ICFallback...  js/src/jit/BaselineIC.cpp:1696
8
9

There are 4 crashes (from 1 installation) in nightly 159 with buildid 20261007095443.

This signature has been reported since build 20261007095443 (2026-10-07), less than a day before the build above.

This bug looks actionable because:

  • gfxUserFontEntry::LoadPlatformFont dereferences a null gfxFontSrcURI in its success-path LOG when a FontFace built from an ArrayBuffer loads while the userfonts log module is enabled at Debug level.

    1. new FontFace(family, arrayBuffer) (here on a DOM Worker) calls InitializeSourceBuffer, and FontFaceSetImpl creates a single gfxFontFaceSrc with mSourceType = eSourceType_Buffer and mBuffer set, leaving mURI null.
    2. gfxUserFontEntry::DoLoadNextSrc takes the buffer branch and calls LoadPlatformFontSync, then LoadPlatformFont, which creates the platform font entry successfully.
    3. The LOG at gfxUserFontSet.cpp:844-849 evaluates mSrcList[aSrcIndex].mURI->GetSpecOrDefault(), so GetSpecOrDefault runs with a null this.
    4. GetSpecOrDefault reads mSimpleURI at offset 0x10 and faults.

    The fault address 0x0000000000000010, the faulting mov rcx, qword [rcx + 0x10], frame 0 at gfxFontSrcURI.cpp:107 (if (mSimpleURI)) and frame 1 at the LOG on line 844 all fit. The offset comes from the declaration order in gfxFontSrcURI.h, not from a layout tool. Because LOG only evaluates its arguments when userfonts Debug logging is on (for example via about:logging or a profiler preset), this only hits users with that logging enabled. The "error making platform font" LOG at lines 789-794 has the same unguarded mURI dereference. Fix first: make both LOGs check mURI (or the source type) before calling GetSpecOrDefault(), for example by printing a placeholder such as "(buffer)" for buffer sources.

  • The failing code comes from c4bf6bc31d90 (gh) (bug 2059824) by :jkew.

Code references:

:jfkthame, as triage owner, can you have a look please?

Filed automatically by Clouseau, which analyses nightly crashes with an LLM. Nothing above was written or checked by a human. Please close it as INVALID if it is wrong — that is useful feedback, not a nuisance.

This is not an independent Mozilla discovery: the crash is known here only because somebody submitted the crash report linked at the top. If this duplicates an existing report, please resolve THIS bug as the duplicate and leave the credit with the earlier reporter.

Flags: needinfo?(jfkthame)

There are now 4 crashes with this signature:

bp-35cfad70-9555-48b4-b448-6d4640261008
bp-44b7d80f-8c71-4f6a-91da-ee2220261008
bp-32702c94-a62a-4ffa-a0bb-4e50b0261008
bp-7a2eaab1-d6d5-4d82-a9e5-c02e20261008

All of them appear to be from the same installation, testing the same URL, served from localhost (127.0.0.1), possibly doing some sort of fuzzing.

The backtrace points to this line, which is MOZ_LOG logging:

https://searchfox.org/firefox-main/rev/3f373ae59cb09e60f4044f9bb37fe27247986234/gfx/thebes/gfxUserFontSet.cpp#844-849

LOG(
    ("userfonts (%p) [src %d] loaded uri: (%s) for (%s) "
     "(%p) gen: %8.8x compress: %d%%\n",
     fontSet.get(), aSrcIndex,
     mSrcList[aSrcIndex].mURI->GetSpecOrDefault().get(), FamilyName().get(),
     this, uint32_t(fontSet->GetGeneration()), fontCompressionRatio));

Apparently mSrcList[aSrcIndex].mURI is null in some cases at that point in the code (which seems maybe-unexpected given the logging that says loaded uri:, implying that we think there's a real URI that should be involved here).

claude was able to generate a testcase for me that triggers this issue (in a session where I've got logging enabled).

My crash report:
https://crash-stats.mozilla.org/report/index/ed8ec4ff-2bba-4f0d-a441-ea8040261009

Here's the testcase. This crashes if you're running with MOZ_LOG=userfonts:5

Attachment #9657035 - Attachment description: buffer-fontface-nulluri-testcase.html → testcase 1 (triggers the bug when running with 'MOZ_LOG=userfonts:5')

A FontFace built from an ArrayBuffer is a buffer source with no URI, so the
LOG() statements must not dereference mSrcList[aSrcIndex].mURI unconditionally.

Note: there are only three SourceType enum values (eSourceType_Local,
eSourceType_URL, eSourceType_Buffer); and eSourceType_Local never reaches this
LoadPlatformFont function. So, our logging is justified in assuming that a null
mURI implies that we're eSourceType_Buffer -- hence the "(buffer)" label.

I've added an assertion at the start of the function to validate this
assumption.

Note, the included WPT has a .ini file to enable logging, so that the test
does actually exercize this logging code (in Firefox) and does serve as a
regression-test. (It crashes when run in the WPT harness in a build without
the fix.)

Assignee: nobody → dholbert
Status: NEW → ASSIGNED
Severity: -- → S3
Flags: needinfo?(jfkthame)
Pushed by dholbert@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/3ba521c5ec56 https://hg.mozilla.org/integration/autoland/rev/f7963917ba10 Guard against null mURI when logging in gfxUserFontEntry::LoadPlatformFont. r=jfkthame
Status: ASSIGNED → RESOLVED
Closed: 7 days ago
Resolution: --- → FIXED
Target Milestone: --- → 160 Branch

The patch landed in nightly and beta is affected.

:dholbert, please make an uplift decision for beta:

  • For beta, nominate the patch for beta uplift approval if the fix should be included in this release, or set status-firefox159 to wontfix if the fix can wait for the next release.

See Requesting an Uplift for documentation on how to request an uplift.

For more information, please visit BugBot documentation.

Flags: needinfo?(dholbert)

Created web-platform-tests PR https://github.com/web-platform-tests/wpt/pull/63557 for changes under testing/web-platform/tests

Upstream PR merged by moz-wptsync-bot

No need to uplift. This is a longstanding defect, which only reproduces if you use hidden diagnostic features to enable just the right sort of logging, so it's unlikely for many users to hit.

Flags: needinfo?(dholbert)
Flags: in-testsuite+
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: