-
Notifications
You must be signed in to change notification settings - Fork 55
Description
GitHub Issue Report — maliit-framework
Environment
Distro: Nobara Linux 43 (Fedora 43 based)
Architecture: x86_64
Compositor: kwin_wayland (KDE Plasma 6)
maliit-framework: 2.3.0-10.fc43
maliit-keyboard: 2.3.1-11.fc43
Qt: qt5-qtbase 5.15.18-1.fc43
Qt Wayland: qt5-qtwayland 5.15.18-1.fc43
Triggering application: Discord Flatpak (com.discordapp.Discord) running in Wayland native mode
Summary
maliit-keyboard can crash when processing a zwp_input_method_context_v1.surrounding_text event containing a very large or non-terminated text payload.
The crash occurs when the implementation performs an unbounded strlen() on the incoming text pointer before passing the result to QString::fromUtf8().
Reproduction
- Start a KDE Plasma Wayland session with maliit configured as the active input method.
- Launch Discord Flatpak in Wayland native mode.
- Focus a text input field inside Discord.
- Trigger a Discord renderer reload (this occurs periodically or during updates).
Result:
maliit-keyboard crashes with SIGSEGV.
KWin restarts the input method automatically, and the crash may repeat several times because the same Wayland event remains queued.
Observed Behavior
handle_surrounding_text receives a const char *text pointer from a Wayland surrounding_text event.
The pointer itself is valid but does not contain a null terminator within the immediately mapped memory region.
The implementation performs:
strlen(text)
with no upper bound.
If the pointer references memory without a nearby null byte, strlen() may traverse a very large region of heap memory (observed ~278 MB) before returning.
The resulting length is then passed to:
QString::fromUtf8(text, len)
During UTF‑8 conversion Qt performs vectorized reads, and when the read crosses a page boundary a SIGSEGV occurs.
Crash Signature
Faulting instruction:
QUtf8::convertToUnicode +144
movdqu (%rax), %xmm0
Notes
The surrounding_text payload originates from a Wayland client via the compositor and therefore should be treated as untrusted input.
A non-null pointer does not guarantee a bounded or valid C string.
Defensive length bounding before conversion would prevent scanning large memory regions or triggering crashes if malformed input is received.
Possible Mitigation
Using a bounded length check before conversion avoids unbounded memory reads:
size_t len = strnlen(text, MAX_SURROUNDING_TEXT);
QString s = QString::fromUtf8(text, len);
This ensures the conversion step operates on a safe, bounded buffer regardless of compositor or client behavior.
Workaround
Running Discord under XWayland avoids triggering the Wayland text-input event:
flatpak override --user --env=ELECTRON_OZONE_PLATFORM_HINT=x11 com.discordapp.Discord
Alternatively, disabling the virtual keyboard input method also prevents the crash.
Additional Evidence
rpm -V confirms packages are intact.
coredumpctl shows consistent crash offsets across occurrences.
Crash loops occur because the compositor restarts the input method while the malformed Wayland event remains queued.
Related Upstream Report
A related report has been filed with KWin regarding the compositor forwarding the surrounding_text payload without a size limit:
https://bugs.kde.org/show_bug.cgi?id=517620
That report focuses on compositor-side validation of the Wayland text-input event. This issue is filed here because maliit currently performs an unbounded strlen() on the incoming pointer, which allows malformed input to trigger a crash regardless of compositor behavior.
Defensive length bounding inside maliit would prevent the crash even if oversized or malformed surrounding_text events are received.