** Description changed:

  Summary
  -------
  Any running GTK4 application crashes with SIGSEGV in
  gdk_surface_handle_event() (gdk/gdksurface.c:2993) when a tablet-pad event
  is dispatched while the client has no keyboard focus. The event carries a
  NULL surface, and GDK_SURFACE_IS_MAPPED() dereferences it without a guard.
+ 
+ This is the Ubuntu 26.04 instance of the upstream reports GNOME/gtk#8285
+ ("Crash during screen configuration change") and GNOME/gtk#8368
+ ("gdk_surface_handle_event: SIGSEGV dereferencing surface in nautilus"), both
+ at gitlab.gnome.org/GNOME/gtk. The fix belongs in GTK: 
gdk_surface_handle_event()
+ must tolerate an event with no surface.
  
  On this machine the crash correlates with the HUION tablet's USB HID
  devices re-enumerating, which happens on resume from suspend. It is not
  application-specific: Nautilus, Ptyxis, gnome-system-monitor and Ghostty
  have all died at the same instruction.
  
  How it was observed
  -------------------
  - Ghostty 1.4.0 (GTK runtime), HUION tablet connected, suspend then
    resume: SIGSEGV one second after "PM: suspend exit", on four out of five
    resumes.
  - Ghostty, no suspend involved: a full re-enumeration of the USB hub the
    tablet is attached to killed it two seconds later (2026-11-02 08:36:41).
  - Nautilus, twelve suspend/resume attempts on the same machine with the
    tablet connected and focused: no crash.
  
  The failure is timing dependent rather than a simple recipe. The likely
  condition is that the client is still processing its Wayland socket when
  the pad re-registers, so GTK has not yet handled wl_keyboard.enter while
  mutter already considers that client focused.
  
  Locking the screen and touching the dial does not reproduce it. With the
  lock screen up, meta_wayland_seat_get_input_focus() returns NULL, so mutter
  assigns the pad no focus client and broadcasts nothing; the application
  never receives the pad event at all.
  
  Steps to reproduce (best effort)
  --------------------------------
  1. Connect a tablet whose pad exposes dial / touch strip / mode groups.
     Tested with HUION Huion Tablet (USB 256c:006d), which presents
     "HUION Huion Tablet Pad", "... Touch Strip" and "... Dial".
  2. Start a GTK4 application and leave it focused (Ghostty 1.4.0 has been
     the most consistent victim here).
  3. Suspend and resume, so the tablet's USB HID devices re-enumerate. Do not
     touch input for a few seconds after resume.
  4. The application exits with SIGSEGV and the kernel logs:
     segfault at 3c ... in libgtk-4.so.1.2200.4[5a33b1,7845712a9000+571000]
  
  Expected behaviour
  ------------------
  The application ignores a pad event it cannot associate with a surface.
  
  Actual behaviour
  ----------------
  kernel: ghostty[84179]: segfault at 3c ip 00007845717783b1 sp ... error 4
          in libgtk-4.so.1.2200.4[5a33b1,7845712a9000+571000] likely on CPU 3
  
  Backtrace
  ---------
  Symbolized with the libgtk-4-1 debug info from debuginfod, build-id
  4c74ae5215a17f78b116635961e03231361bf671:
  
    #0  gdk_surface_handle_event.isra.0 (event=...) at gdk/gdksurface.c:2993
    #1  _gdk_event_emit (event=...) at gdk/gdkevents.c:491
    #2  gdk_event_source_dispatch (...) at gdk/gdkeventsource.c
    #3  g_main_context_dispatch_unlocked
    #4  g_main_context_iterate_unlocked
    #5  g_main_context_iteration
    #6  g_application_run
  
  gdk/gdksurface.c:2987-2994 in 4.22.4:
  
    gboolean
    gdk_surface_handle_event (GdkEvent *event)
    {
      GdkSurface *surface = gdk_event_get_surface (event);
      gint64 begin_time = GDK_PROFILER_CURRENT_TIME;
      gboolean handled = FALSE;
  
      if (!GDK_SURFACE_IS_MAPPED (surface))   /* line 2993 */
        return FALSE;
  
  GDK_SURFACE_IS_MAPPED is ((surface)->pending_is_mapped)
  (gdk/gdksurfaceprivate.h:172). Disassembling the crashing instruction
  confirms the mechanism:
  
    5a33b1:  41 8b 4c 24 3c      mov  0x3c(%r12),%ecx     ; r12 == NULL
  
  The fault address reported by the kernel is 0x3c, i.e. surface == NULL and
  pending_is_mapped at struct offset 0x3c.
  
  Root cause
  ----------
  _gdk_event_emit() (gdk/gdkevents.c:491) hands every event to
  gdk_surface_handle_event(), which assumes the event has a surface.
  
  The Wayland backend builds tablet-pad events with seat->keyboard_focus as
  their surface (gdk/wayland/gdkseat-wayland.c):
  
    tablet_pad_ring_handle_frame               line 3379
    tablet_pad_strip_handle_frame              line 3456
    tablet_pad_group_handle_mode_switch        line 3582
    tablet_pad_dial_handle_frame               line 3619
    tablet_pad_button_handle_button            line 3755
  
  seat->keyboard_focus is NULL whenever GTK has no keyboard focus surface,
  which is the case in the window between resume and the arrival of
  wl_keyboard.enter. The pad event is then queued with surface == NULL and
  crashes the first GTK4 client that dispatches it.
  
  The compositor side is what makes this fire on resume. When a pad
  registers, mutter assigns it the current input focus and broadcasts the
  pad's mode, from src/wayland/meta-wayland-tablet-pad-group.c:
  
    meta_wayland_tablet_pad_group_sync_focus (MetaWaylandTabletPadGroup *group)
    {
      ...
      if (!wl_list_empty (&group->focus_resource_list))
        {
          broadcast_group_mode (group, clutter_get_current_event_time ());
  
  meta_wayland_tablet_seat_device_added() picks that focus from
  meta_wayland_seat_get_input_focus (seat) at the moment the device appears
  (src/wayland/meta-wayland-tablet-seat.c). During resume the pad
  re-registers while the seat still points at the previously focused client,
  but GTK has not yet received the new keyboard enter, so
  seat->keyboard_focus is still NULL when the mode_switch arrives.
  
  Upstream GTK issue #8285 contains a gdb dump of the same event, confirming
  the event type and the NULL surface:
  
    (gdb) p *event
    $8 = {
      event_type = GDK_PAD_GROUP_MODE,
      surface = 0x0,
      device = 0x55e60969b4f0,
      ...
    }
  
  Scope on this machine
  ---------------------
  Same instruction, same fault address, different applications:
  
    2026-07-27  gnome-system-monitor
    2026-09-11  ptyxis
    2026-09-17  ptyxis
    2026-09-21  nautilus
    2026-09-23  nautilus
    2026-11-01  ghostty
    2026-11-02  ghostty (three times)
    2026-11-03  ghostty
  
  all reported as:
    segfault at 3c ... in libgtk-4.so.1.2200.4[5a33b1,...]
  
  Four of the Ghostty crashes land one second after "PM: suspend exit". The
  remaining one (2026-11-02 08:36:41) happened during a full re-enumeration
  of the USB hub the tablet is attached to, with no suspend involved:
  
    08:36:38  usb 1-12: new high-speed USB device number 9
    08:36:39  input: HUION Huion Tablet Pad as /devices/.../input/input37
    08:36:39  input: HUION Huion Tablet Touch Strip as .../input38
    08:36:39  input: HUION Huion Tablet Dial as .../input39
    08:36:41  kernel: ghostty[67283]: segfault at 3c ...
  
  Upstream
  --------
  - GNOME/gtk#8285 "Crash during screen configuration change"
    https://gitlab.gnome.org/GNOME/gtk/-/work_items/8285
  - GNOME/gtk#8368 "gdk_surface_handle_event: SIGSEGV dereferencing surface
    in nautilus (GDK_SURFACE_IS_MAPPED, gdksurface.c:2993)"
    https://gitlab.gnome.org/GNOME/gtk/-/work_items/8368
  
  Both are open. The missing NULL check is present in 4.22.4, still present
  in 4.22.5 and on the gtk-4-22 branch, so no upstream point release fixes
  this at the time of filing.
  
  No duplicate found in ubuntu/+source/gtk4 on Launchpad.
  
  Proposed fix
  ------------
  Minimal guard in gdk/gdksurface.c:
  
      GdkSurface *surface = gdk_event_get_surface (event);
      gint64 begin_time = GDK_PROFILER_CURRENT_TIME;
      gboolean handled = FALSE;
  
    + if (surface == NULL)
    +   return FALSE;
    +
      if (!GDK_SURFACE_IS_MAPPED (surface))
        return FALSE;
  
  A broader fix would be to make _gdk_event_emit() skip surface-bearing event
  types when gdk_event_get_surface() returns NULL, and/or to stop using
  seat->keyboard_focus as the surface for pad events, since pad events are
  device-level and not tied to a window.
  
  Workaround
  ----------
  Unplugging the tablet before suspending prevents the crash. Setting
  GDK_BACKEND=x11 for the affected application also avoids it: the X11
  backend creates no tablet-pad events at all.
  
  Environment
  -----------
  Ubuntu 26.04.1 LTS (resolute), amd64
  libgtk-4-1          4.22.4+ds-0ubuntu0.1  (resolute-updates)
  libglib2.0-0t64     2.88.0-1ubuntu0.1
  libwayland-client0  1.24.0-2
  gnome-shell         50.1-0ubuntu1.4
  mutter              50.1
  Linux 7.0.0-42-generic
  GNOME on Wayland (XDG_SESSION_TYPE=wayland)
  Display on AMD Granite Ridge iGPU (amdgpu); GTK uses Mesa EGL 4.6
  Tablet: HUION Huion Tablet, USB 256c:006d
  
  Ghostty is the classic Snap (ghostty v1.4.0, rev 1016), i.e. it links
  against the host libgtk-4-1, not a bundled GTK; the crash is unrelated to
  Snap packaging.
  
  Note on the attachment
  ----------------------
  journal-suspend-crash.txt contains all ten crashes, the resume window with
  the USB re-enumeration, the non-suspend crash, the suspend history and the
  tablet device list. No .crash file is attached: Ghostty is a classic Snap
  and Snap crashes are not collected by apport, and the failure could not be
  reproduced on demand with a packaged application.

** Description changed:

  Summary
  -------
+ Upstream GTK reports: GNOME/gtk#8285 ("Crash during screen configuration
+ change") and GNOME/gtk#8368 ("gdk_surface_handle_event: SIGSEGV dereferencing
+ surface in nautilus"), both at gitlab.gnome.org/GNOME/gtk. This bug is the
+ Ubuntu 26.04 instance of them.
+ 
  Any running GTK4 application crashes with SIGSEGV in
  gdk_surface_handle_event() (gdk/gdksurface.c:2993) when a tablet-pad event
  is dispatched while the client has no keyboard focus. The event carries a
  NULL surface, and GDK_SURFACE_IS_MAPPED() dereferences it without a guard.
- 
- This is the Ubuntu 26.04 instance of the upstream reports GNOME/gtk#8285
- ("Crash during screen configuration change") and GNOME/gtk#8368
- ("gdk_surface_handle_event: SIGSEGV dereferencing surface in nautilus"), both
- at gitlab.gnome.org/GNOME/gtk. The fix belongs in GTK: 
gdk_surface_handle_event()
- must tolerate an event with no surface.
+ The fix belongs in GTK: gdk_surface_handle_event() must tolerate an event
+ with no surface.
  
  On this machine the crash correlates with the HUION tablet's USB HID
  devices re-enumerating, which happens on resume from suspend. It is not
  application-specific: Nautilus, Ptyxis, gnome-system-monitor and Ghostty
  have all died at the same instruction.
  
  How it was observed
  -------------------
  - Ghostty 1.4.0 (GTK runtime), HUION tablet connected, suspend then
    resume: SIGSEGV one second after "PM: suspend exit", on four out of five
    resumes.
  - Ghostty, no suspend involved: a full re-enumeration of the USB hub the
    tablet is attached to killed it two seconds later (2026-11-02 08:36:41).
  - Nautilus, twelve suspend/resume attempts on the same machine with the
    tablet connected and focused: no crash.
  
  The failure is timing dependent rather than a simple recipe. The likely
  condition is that the client is still processing its Wayland socket when
  the pad re-registers, so GTK has not yet handled wl_keyboard.enter while
  mutter already considers that client focused.
  
  Locking the screen and touching the dial does not reproduce it. With the
  lock screen up, meta_wayland_seat_get_input_focus() returns NULL, so mutter
  assigns the pad no focus client and broadcasts nothing; the application
  never receives the pad event at all.
  
  Steps to reproduce (best effort)
  --------------------------------
  1. Connect a tablet whose pad exposes dial / touch strip / mode groups.
     Tested with HUION Huion Tablet (USB 256c:006d), which presents
     "HUION Huion Tablet Pad", "... Touch Strip" and "... Dial".
  2. Start a GTK4 application and leave it focused (Ghostty 1.4.0 has been
     the most consistent victim here).
  3. Suspend and resume, so the tablet's USB HID devices re-enumerate. Do not
     touch input for a few seconds after resume.
  4. The application exits with SIGSEGV and the kernel logs:
     segfault at 3c ... in libgtk-4.so.1.2200.4[5a33b1,7845712a9000+571000]
  
  Expected behaviour
  ------------------
  The application ignores a pad event it cannot associate with a surface.
  
  Actual behaviour
  ----------------
  kernel: ghostty[84179]: segfault at 3c ip 00007845717783b1 sp ... error 4
          in libgtk-4.so.1.2200.4[5a33b1,7845712a9000+571000] likely on CPU 3
  
  Backtrace
  ---------
  Symbolized with the libgtk-4-1 debug info from debuginfod, build-id
  4c74ae5215a17f78b116635961e03231361bf671:
  
    #0  gdk_surface_handle_event.isra.0 (event=...) at gdk/gdksurface.c:2993
    #1  _gdk_event_emit (event=...) at gdk/gdkevents.c:491
    #2  gdk_event_source_dispatch (...) at gdk/gdkeventsource.c
    #3  g_main_context_dispatch_unlocked
    #4  g_main_context_iterate_unlocked
    #5  g_main_context_iteration
    #6  g_application_run
  
  gdk/gdksurface.c:2987-2994 in 4.22.4:
  
    gboolean
    gdk_surface_handle_event (GdkEvent *event)
    {
      GdkSurface *surface = gdk_event_get_surface (event);
      gint64 begin_time = GDK_PROFILER_CURRENT_TIME;
      gboolean handled = FALSE;
  
      if (!GDK_SURFACE_IS_MAPPED (surface))   /* line 2993 */
        return FALSE;
  
  GDK_SURFACE_IS_MAPPED is ((surface)->pending_is_mapped)
  (gdk/gdksurfaceprivate.h:172). Disassembling the crashing instruction
  confirms the mechanism:
  
    5a33b1:  41 8b 4c 24 3c      mov  0x3c(%r12),%ecx     ; r12 == NULL
  
  The fault address reported by the kernel is 0x3c, i.e. surface == NULL and
  pending_is_mapped at struct offset 0x3c.
  
  Root cause
  ----------
  _gdk_event_emit() (gdk/gdkevents.c:491) hands every event to
  gdk_surface_handle_event(), which assumes the event has a surface.
  
  The Wayland backend builds tablet-pad events with seat->keyboard_focus as
  their surface (gdk/wayland/gdkseat-wayland.c):
  
    tablet_pad_ring_handle_frame               line 3379
    tablet_pad_strip_handle_frame              line 3456
    tablet_pad_group_handle_mode_switch        line 3582
    tablet_pad_dial_handle_frame               line 3619
    tablet_pad_button_handle_button            line 3755
  
  seat->keyboard_focus is NULL whenever GTK has no keyboard focus surface,
  which is the case in the window between resume and the arrival of
  wl_keyboard.enter. The pad event is then queued with surface == NULL and
  crashes the first GTK4 client that dispatches it.
  
  The compositor side is what makes this fire on resume. When a pad
  registers, mutter assigns it the current input focus and broadcasts the
  pad's mode, from src/wayland/meta-wayland-tablet-pad-group.c:
  
    meta_wayland_tablet_pad_group_sync_focus (MetaWaylandTabletPadGroup *group)
    {
      ...
      if (!wl_list_empty (&group->focus_resource_list))
        {
          broadcast_group_mode (group, clutter_get_current_event_time ());
  
  meta_wayland_tablet_seat_device_added() picks that focus from
  meta_wayland_seat_get_input_focus (seat) at the moment the device appears
  (src/wayland/meta-wayland-tablet-seat.c). During resume the pad
  re-registers while the seat still points at the previously focused client,
  but GTK has not yet received the new keyboard enter, so
  seat->keyboard_focus is still NULL when the mode_switch arrives.
  
  Upstream GTK issue #8285 contains a gdb dump of the same event, confirming
  the event type and the NULL surface:
  
    (gdb) p *event
    $8 = {
      event_type = GDK_PAD_GROUP_MODE,
      surface = 0x0,
      device = 0x55e60969b4f0,
      ...
    }
  
  Scope on this machine
  ---------------------
  Same instruction, same fault address, different applications:
  
    2026-07-27  gnome-system-monitor
    2026-09-11  ptyxis
    2026-09-17  ptyxis
    2026-09-21  nautilus
    2026-09-23  nautilus
    2026-11-01  ghostty
    2026-11-02  ghostty (three times)
    2026-11-03  ghostty
  
  all reported as:
    segfault at 3c ... in libgtk-4.so.1.2200.4[5a33b1,...]
  
  Four of the Ghostty crashes land one second after "PM: suspend exit". The
  remaining one (2026-11-02 08:36:41) happened during a full re-enumeration
  of the USB hub the tablet is attached to, with no suspend involved:
  
    08:36:38  usb 1-12: new high-speed USB device number 9
    08:36:39  input: HUION Huion Tablet Pad as /devices/.../input/input37
    08:36:39  input: HUION Huion Tablet Touch Strip as .../input38
    08:36:39  input: HUION Huion Tablet Dial as .../input39
    08:36:41  kernel: ghostty[67283]: segfault at 3c ...
  
  Upstream
  --------
  - GNOME/gtk#8285 "Crash during screen configuration change"
    https://gitlab.gnome.org/GNOME/gtk/-/work_items/8285
  - GNOME/gtk#8368 "gdk_surface_handle_event: SIGSEGV dereferencing surface
    in nautilus (GDK_SURFACE_IS_MAPPED, gdksurface.c:2993)"
    https://gitlab.gnome.org/GNOME/gtk/-/work_items/8368
  
  Both are open. The missing NULL check is present in 4.22.4, still present
  in 4.22.5 and on the gtk-4-22 branch, so no upstream point release fixes
  this at the time of filing.
  
  No duplicate found in ubuntu/+source/gtk4 on Launchpad.
  
  Proposed fix
  ------------
  Minimal guard in gdk/gdksurface.c:
  
      GdkSurface *surface = gdk_event_get_surface (event);
      gint64 begin_time = GDK_PROFILER_CURRENT_TIME;
      gboolean handled = FALSE;
  
    + if (surface == NULL)
    +   return FALSE;
    +
      if (!GDK_SURFACE_IS_MAPPED (surface))
        return FALSE;
  
  A broader fix would be to make _gdk_event_emit() skip surface-bearing event
  types when gdk_event_get_surface() returns NULL, and/or to stop using
  seat->keyboard_focus as the surface for pad events, since pad events are
  device-level and not tied to a window.
  
  Workaround
  ----------
  Unplugging the tablet before suspending prevents the crash. Setting
  GDK_BACKEND=x11 for the affected application also avoids it: the X11
  backend creates no tablet-pad events at all.
  
  Environment
  -----------
  Ubuntu 26.04.1 LTS (resolute), amd64
  libgtk-4-1          4.22.4+ds-0ubuntu0.1  (resolute-updates)
  libglib2.0-0t64     2.88.0-1ubuntu0.1
  libwayland-client0  1.24.0-2
  gnome-shell         50.1-0ubuntu1.4
  mutter              50.1
  Linux 7.0.0-42-generic
  GNOME on Wayland (XDG_SESSION_TYPE=wayland)
  Display on AMD Granite Ridge iGPU (amdgpu); GTK uses Mesa EGL 4.6
  Tablet: HUION Huion Tablet, USB 256c:006d
  
  Ghostty is the classic Snap (ghostty v1.4.0, rev 1016), i.e. it links
  against the host libgtk-4-1, not a bundled GTK; the crash is unrelated to
  Snap packaging.
  
  Note on the attachment
  ----------------------
  journal-suspend-crash.txt contains all ten crashes, the resume window with
  the USB re-enumeration, the non-suspend crash, the suspend history and the
  tablet device list. No .crash file is attached: Ghostty is a classic Snap
  and Snap crashes are not collected by apport, and the failure could not be
  reproduced on demand with a packaged application.

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2172827

Title:
  gtk4 4.22.4: SIGSEGV in gdk_surface_handle_event() on a tablet-pad
  event carrying no surface (GDK_PAD_GROUP_MODE) after USB re-
  enumeration

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/gtk4/+bug/2172827/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to