CachyOS / CachyOS/packageinstaller

SIGSEGV in ~QMessageBox on Plasma - native message dialog helper is used after free

Open Beginner friendly
#68 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
23
Forks
30
PR merge metrics
No merged PRs in 30d

Description

cachyos-pi 1.6.2, Qt 6.11.2, plasma-integration 6.7.4, Plasma 6 / Wayland.

What I did: a package install was running (pkexec pacman -S krita), I pressed "About" and
closed the About box. The app died with SIGSEGV. The core dump is kept, key frames below.

What happens: on Plasma our message boxes are shown as native dialogs.
KDEPlatformMessageDialogHelper::show() creates its own QMessageBox, sets Qt::WA_DeleteOnClose
on it and keeps a raw pointer to it. QDialog::exec() deletes that dialog when it closes, so
the helper keeps a dangling pointer. Later, when our QMessageBox is destroyed,
~QMessageBox -> QMessageBoxPrivate::setVisible(false) -> QDialogPrivate::setNativeDialogVisible(false)
-> helper->hide() -> m_dialog->hide() reads the freed object and calls through a garbage vtable.

Key frames from the core:

```
#0 0x0000000000000071 <- jump through freed vtable
#1 QDialogPrivate::setNativeDialogVisible(bool)
#2 QMessageBoxPrivate::setVisible(bool)
#3 QMessageBox::~QMessageBox()
#4 about::display_about_msgbox() (src/about.cpp:16)
In the core: nativeDialogInUse = 1, m_platformHelper is a KDEPlatformMessageDialogHelper, and
its m_dialog member points into a freed 40-byte block. Its hide() is literally
`mov 0x20(%rdi),%rdi; jmp QWidget::hide` - no null check, no QPointer.
```

The defect itself is in plasma-integration and I am reporting it there too, but every
QMessageBox in the app is exposed to it, so the patch below simply keeps Qt's own dialogs.
Nothing changes visually - the "native" Plasma dialog is a QMessageBox as well.

What I measured: with the patch the helper dialog is never created - 10 About/License cycles
under a debugger, zero helper QMessageBox constructions and zero setNativeDialogVisible calls,
app alive. Without the patch the helper dialog is created and destroyed before our own box on
every single About click, i.e. the dangling pointer is there every time.

### Patch

```diff

diff --git a/src/main.cpp b/src/main.cpp
index bd9fb40..a1b964a 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -138,6 +138,12 @@ auto main(int argc, char** argv) -> std::int32_t {
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif

+ // Keep using Qt's own dialogs. The Plasma platform theme creates a helper QMessageBox
+ // for every native message dialog, marks it WA_DeleteOnClose and keeps a raw pointer
+ // to it. QDialog::exec() deletes that helper dialog when it closes, so the later
+ // hide() call from ~QMessageBox dereferences freed memory and can kill the app.
+ QApplication::setAttribute(Qt::AA_DontUseNativeDialogs);
+
/// 2. Application identification
QApplication::setOrganizationName("cachyos");
QApplication::setOrganizationDomain("cachyos.org");
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in src/main.cpp around main(), where application attributes are configured, and review the reported native-dialog setting. Exercise the About and License dialogs under a debugger, as in the report. Done means the Plasma helper QMessageBox is not constructed, setNativeDialogVisible is not called, and repeated dialog cycles do not crash.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
desktop
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
85/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.