Package: libqt5gui5
Version: 5.15.13+dfsg
Severity: important
Dear Maintainers (dear Dmitry, if I've just assembled my new package
knowledge correctly ;),
Qt has a confirmed bug in fallback handling for fontconfig that causes
arbitrary crashes in every Qt-based application.
Here is the respective debug trace snippet from my machine:
Thread 1 "keepassxc" received signal SIGSEGV, Segmentation fault.
0x00007ffff1e41d51 in ?? () from
/lib/x86_64-linux-gnu/libfontconfig.so.1
(gdb) bt
#0 0x00007ffff1e41d51 in ??? () at
/lib/x86_64-linux-gnu/libfontconfig.so.1
#1 0x00007ffff1e424f7 in FcCharSetHasChar () at
/lib/x86_64-linux-gnu/libfontconfig.so.1
#2 0x00007ffff1f6b900 in ??? () at
/lib/x86_64-linux-gnu/libQt5XcbQpa.so.5
#3 0x00007ffff682a383 in QFontEngineMulti::stringToCMap
(this=<optimized out>, str=<optimized out>, len=<optimized out>,
glyphs=<optimized out>, nglyphs=0x7fffffffb7fc, flags=...) at
text/qfontengine.cpp:1933
In my specific case KeePassXC suddenly began to crash when I tried to
open sub-folders or even when I only tried to select "About" within the
menu. This behaviour apparently started after the fontconfig package
received an update.
Some debugging and researching then lead to the discovery that this
indeed is a bug in Qt and that it luckily already has been fixed
upstream:
https://codereview.qt-project.org/c/qt/qtbase/+/750214
The commit:
https://code.qt.io/cgit/qt/qtbase.git/commit/?id=80ddc8dee6a05cd6
But sadly it only made it into the very recent Qt6 versions mentioned in
the commit.
I'm new to this and never have filed a bug for any distro before. Here
is what I've done so far:
- Built Qt5 and Qt6 from source and can confirm that the patch fixes the
issues (Qt5 drop-in replacement: libQt5XcbQpa.so.5.15.13).
- Followed these instructions to create a patch:
https://salsa.debian.org/qt-kde-team/qt/qtbase/-/blob/master/debian/README.source
There I've verified that the fix is not already part of debian/patches.
Now I would appreciate some guidance how to proceed with the patch /
backporting to other Qt versions, since all versions below Qt6 are
affected.
Is it sufficient to supply the patch (as attached to this mail)? I can
offer to create an account and merge request on Salsa, as well as help
backporting, if you like.
Note that I ran into the issue on Linux Mint 22.3 (Zena), based on
Ubuntu 24.04 (Noble), obviously based on Debian :)
So I would be grateful for any hints if and how I shall provide the
patch downstream as well. I'm actually a bit overwhelmed with all the
possible ways where, whom and how to provide the patch.
Please find the patch for Qt5 attached and let me know if I can assist
any further.
Thanks and have a great weekend,
Michael
From ed1117d84851007fd2bb6bf7fa45e8985c0e3067 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Imre=20P=C3=A9ntek?= <[email protected]>
Date: Sat, 17 Oct 2026 22:46:26 +0200
Subject: [PATCH] Fix crash when fontconfig fallback pattern has no charset
QFontEngineMultiFontConfig::shouldLoadFontEngineForCharacter() passed
the address of an uninitialized FcCharSet* to FcPatternGetCharSet()
and then called FcCharSetHasChar() on it without checking the result.
A pattern returned by FcFontMatch() is not guaranteed to carry an
FC_CHARSET element: fontconfig treats the charset as optional, and
caches produced by other fontconfig builds (e.g. a bundled snapshot
that indexed .woff/.woff2 files it could not parse as empty patterns)
can legally serve charset-less patterns. In that case the uninitialized
pointer is dereferenced inside FcCharSetHasChar() and the process
crashes with SIGSEGV; builds hardened with
-ftrivial-auto-var-init=pattern crash deterministically at 0xfefe...
Observed in the wild on Arch/Manjaro after the fontconfig 2.18.1
upgrade: every Qt application (Qt Creator, CopyQ, KeePassXC, ...)
crashed in FcCharSetHasChar via QFontEngineMulti::glyphIndex() as soon
as any glyph fallback lookup ran, because stale fontconfig caches
served a charset-less pattern for every FcFontMatch() call.
Initialize the pointer and check the FcPatternGetCharSet() result.
When no charset can be obtained, keep the optimistic default (load the
engine) exactly as we already do when no match pattern is available,
so glyph coverage is decided by the font engine itself.
Pick-to: 6.12 6.11 6.8
Change-Id: I18687e0a7b7a0019a459155395636768ad9ea964
Reviewed-by: Joerg Bornemann <[email protected]>
Origin: upstream, https://code.qt.io/cgit/qt/qtbase.git/commit/?id=80ddc8dee6a05cd6
Signed-off-by: Michael Schuster <[email protected]>
---
.../fontconfig/qfontenginemultifontconfig.cpp | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp
index cbf0793d..70345b69 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontenginemultifontconfig.cpp
@@ -61,9 +61,11 @@ bool QFontEngineMultiFontConfig::shouldLoadFontEngineForCharacter(int at, uint u
bool charSetHasChar = true;
FcPattern *matchPattern = getMatchPatternForFallback(at - 1);
if (matchPattern != nullptr) {
- FcCharSet *charSet;
- FcPatternGetCharSet(matchPattern, FC_CHARSET, 0, &charSet);
- charSetHasChar = FcCharSetHasChar(charSet, ucs4);
+ FcCharSet *charSet = nullptr;
+ if (FcPatternGetCharSet(matchPattern, FC_CHARSET, 0, &charSet) == FcResultMatch
+ && charSet != nullptr) {
+ charSetHasChar = FcCharSetHasChar(charSet, ucs4);
+ }
}
return charSetHasChar;
--
2.43.0