https://bugs.kde.org/show_bug.cgi?id=517620

            Bug ID: 517620
           Summary: Wayland: KWin forwards unbounded
                    zwp_input_method_context_v1.surrounding_text causing
                    maliit-keyboard crash
    Classification: Plasma
           Product: kwin
      Version First unspecified
       Reported In:
          Platform: Fedora RPMs
                OS: Linux
            Status: REPORTED
          Severity: crash
          Priority: NOR
         Component: wayland-generic
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: ---

Created attachment 190694
  --> https://bugs.kde.org/attachment.cgi?id=190694&action=edit
coredumpctl info maliit-keyboard

Wayland protocol: zwp_text_input_v3 →
zwp_input_method_context_v1.surrounding_text

kwin 6.6.2

ENVIRONMENT

Distro: Nobara Linux 43 (Fedora 43-based), x86_64
Compositor: kwin_wayland (KDE Plasma 6, plasma-kwin_wayland.service)
Packages: kwin 6.x (updated 2026-03-14), maliit-framework 2.3.0-10.fc43,
maliit-keyboard 2.3.1-11.fc43, qt5-qtbase 5.15.18-1.fc43, qt5-qtwayland
5.15.18-1.fc43
Triggering application: Discord (Electron/Chromium, com.discordapp.Discord
flatpak, Wayland native mode)
REPRODUCTION STEPS

Start KDE Plasma Wayland session with maliit configured as the active input
method.
Launch Discord flatpak with Wayland native mode (default on Plasma).
Focus any text input field inside Discord and type text.
Allow or trigger a Discord renderer reload (e.g., navigate between channels
rapidly; also occurs on background auto-update).
Observe maliit-keyboard crash. Repeat immediately — crash loop fires 3–4 times
within 2 seconds.
OBSERVED BEHAVIOR

Discord emits zwp_text_input_v3.set_surrounding_text with a text payload whose
effective strlen is ~278,000,000 bytes (no null terminator within the mapped
heap region). KWin forwards this as
zwp_input_method_context_v1.surrounding_text to maliit without capping or
validating the payload length. maliit crashes (SIGSEGV). KWin logs:

KWin immediately relaunches maliit. The malformed event remains in the Wayland
dispatch queue and is reprocessed, causing the same crash within milliseconds.
This repeats 3–4 times before the input context clears.

Crash loop timestamps (single event, multiple restarts):

EXPECTED BEHAVIOR

The compositor should enforce a maximum byte length on surrounding_text
payloads before forwarding to any input method process. The zwp_text_input_v3
protocol is designed to convey small cursor-context text; large document bodies
are outside the intended scope. Chromium/Electron is known to send full
document text in some scenarios. Sanitisation is the compositor's
responsibility at this trust boundary.

CRASH SIGNATURE

Faulting instruction: movdqu (%rax), %xmm0 — 16-byte SSE2 load at
QUtf8::convertToUnicode+144, source pointer 11 bytes before an unmapped page
boundary.

ROOT CAUSE ANALYSIS

Verified facts:

Discord sends set_surrounding_text with a non-null text pointer that has no
null byte for ~278 MB across contiguous heap allocations.
KWin forwards the event to maliit without enforcing any length limit.
maliit calls strlen(text) → returns 278,012,691. This value is passed as the
len argument to QString::fromUtf8_helper.
Qt5's SSE2 UTF-8 path processes 16 bytes at a time; after ~84 KB the read
pointer crosses a page boundary at 0x5584c28f8000 → SIGSEGV.
Because KWin restarts maliit immediately and the event queue is not cleared,
the crash loop repeats.
rpm -V on all involved packages returned no output — files match their RPMs;
this is not a packaging regression.

COMPONENT RESPONSIBILITY

Component       Role
Discord (Electron/Wayland)      Trigger — sends oversized surrounding_text on
renderer reload
KWin    Primary enabler — forwards event to input method without length
enforcement
maliit-framework        Crash vector — calls strlen on untrusted protocol input
Qt5 QUtf8::convertToUnicode     Final fault site — SSE2 read crosses page
boundary
PROTOCOL NOTE

zwp_text_input_v3 (§set_surrounding_text) does not mandate a length limit, but
the protocol intent is to carry a small surrounding-cursor text context.
Implementations are expected to send no more than a few thousand bytes. The
compositor sits at the trust boundary between arbitrary Wayland clients and
privileged input method processes; enforcing a cap (e.g., 4096 or 65536 bytes)
before forwarding via zwp_input_method_context_v1.surrounding_text is the
appropriate mitigation at the compositor layer.

WORKAROUND

Force Discord to use XWayland (prevents native Wayland text input events):

Reversible: flatpak override --user --unset-env=ELECTRON_OZONE_PLATFORM_HINT
com.discordapp.Discord

Disable virtual keyboard entirely:

ADDITIONAL DEBUGGING EVIDENCE

Discord flatpak log immediately preceding every crash instance (consistent
across all boots and dates):

Crash reproduced across multiple boots, first occurrence 2026-03-10. Identical
fault address offset (libQt5Core.so.5+0x278670) in every instance.

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to