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

            Bug ID: 526360
           Summary: Wayland crash from dangling QQuickItem in
                    SystemTray::openContextMenu when tray application
                    exits during asynchronous menu request
    Classification: Plasma
           Product: plasmashell
      Version First 6.7.5
       Reported In:
          Platform: Arch Linux
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: System Tray widget
          Assignee: [email protected]
          Reporter: [email protected]
                CC: [email protected]
  Target Milestone: 1.0

Created attachment 196631
  --> https://bugs.kde.org/attachment.cgi?id=196631&action=edit
kcrash backtrace

# DESCRIPTION

plasmashell crashes on Wayland when a StatusNotifierItem disappears while its
context-menu request is still pending.

The crash occurred after clicking a stale qBittorrent tray icon, around the
time I killed the qBittorrent process.

# STEPS TO REPRODUCE

1. A stale qBittorrent StatusNotifierItem was visible in the system tray.
2. I right-clicked the icon to see what's up.
3. I attempted to kill the qBittorrent process around the same time.
4. plasmashell crashed while the asynchronous D-Bus menu update completed.

# SOFTWARE/OS VERSIONS

Operating System: Arch Linux 
KDE Plasma Version: 6.7.5
KDE Frameworks Version: 6.30.0
Qt Version: 6.11.2
Graphics Platform: Wayland

# CRASH ANALYSIS

SystemTray::openContextMenu() in applets/systemtray/systemtray.cpp captures
statusNotifierIcon as a raw QQuickItem pointer here:

    connect(
        source,
        &StatusNotifierItemSource::contextMenuReady,
        this,
        [this, statusNotifierIcon, pos](QMenu *menu) {
            if (menu && !menu->isEmpty()) {
                KAcceleratorManager::manage(menu);

                if (KWindowSystem::isPlatformWayland()) {
                    showSystemTrayMenuWayland(menu, statusNotifierIcon,
location());
                } else {
                    showSystemTrayMenuX11(menu, statusNotifierIcon, pos,
location());

                    // Workaround for QTBUG-59044
                    if (auto item =
statusNotifierIcon->window()->mouseGrabberItem()) {
                        item->ungrabMouse();
                    }
                }
            }
        },
        Qt::SingleShotConnection);

https://invent.kde.org/plasma/plasma-workspace/-/blob/v6.7.5/applets/systemtray/systemtray.cpp#L627
https://invent.kde.org/plasma/plasma-workspace/-/blob/v6.7.5/applets/systemtray/systemtray.cpp#L92

The context-menu request is asynchronous. If the StatusNotifierItem disappears
while the request is pending, the corresponding QML delegate may be destroyed
while the callback still holds its raw pointer.

Using SystemTray as the connection context protects the callback against
destruction of SystemTray, but not against destruction of the captured
QQuickItem.
Qt::SingleShotConnection does not provide lifetime tracking for captured
objects either.

When contextMenuReady is emitted, the callback passes the dangling pointer to
showSystemTrayMenuWayland(), which dereferences it here:

    QWindow *trayWindow = trayItem->window();

The backtrace and the invalid QObject private data at the point of the crash
are consistent with this use-after-free.

The stale qBittorrent icon disappearing around the time its process was
terminated is most likely trigger for this race.

# BACKTRACE EXCERPT

#5  0x00007fea64179698 in QQuickItem::window (this=this@entry=0x55de9a1da870)
at
/usr/src/debug/qt6-declarative/qtdeclarative/src/quick/items/qquickitem.cpp:3010
#6  0x00007fea58ef616a in showSystemTrayMenuWayland (menu=0x55de921d98c0,
trayItem=0x55de9a1da870, location=Plasma::Types::BottomEdge)
    at
/usr/src/debug/plasma-workspace/plasma-workspace-6.7.5/applets/systemtray/systemtray.cpp:92
#10 StatusNotifierItemSource::contextMenuReady (this=0x55de96b65560,
_t1=<optimized out>)
    at
/usr/src/debug/plasma-workspace/build/applets/systemtray/systemtray_static_autogen/include/moc_statusnotifieritemsource.cpp:196
#11 operator() (__closure=<optimized out>, menu=0x55de921d98c0) at
/usr/src/debug/plasma-workspace/plasma-workspace-6.7.5/applets/systemtray/statusnotifieritemsource.cpp:452
#20 DBusMenuImporter::menuUpdated (this=0x55de97048d40, _t1=<optimized out>) at
/usr/src/debug/plasma-workspace/build/libdbusmenuqt/dbusmenuqt_autogen/include/moc_dbusmenuimporter.cpp:189
#21 DBusMenuImporter::slotAboutToShowDBusCallFinished (this=0x55de97048d40,
watcher=0x55de940f6af0)
    at
/usr/src/debug/plasma-workspace/plasma-workspace-6.7.5/libdbusmenuqt/dbusmenuimporter.cpp:499

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

Reply via email to