QMainWindowPrivate::layout - use QPointer instead of bare pointer

qt_mainwindow_layout(mainWindow) returns the pointer to a stale object,
if the layout has already been deleted.

Most users of qt_mainwindow_layout() assert the returned pointer, or
handle nullptr explicitly. If the mainwindow layout has already been
deleted, they will still access it. While this has not lead to (known)
issues yet, a UAF exception is thrown in an ASAN build.

=> Use a QPointer instead of a bare pointer.
=> Add missing nullptr check in QDockWidgetPrivate::endDrag()

Pick-to: 6.6 6.5
Change-Id: I3484b53e0e2213b82085ceed3ffa66913947189f
Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
Axel Spoerl 2023-11-29 19:43:04 +01:00
parent a42e907b69
commit 1914f62c31
2 changed files with 6 additions and 2 deletions

View File

@ -815,6 +815,10 @@ void QDockWidgetPrivate::endDrag(EndDragMode mode)
Q_ASSERT(mainWindow != nullptr);
QMainWindowLayout *mwLayout = qt_mainwindow_layout(mainWindow);
// if mainWindow is being deleted in an ongoing drag, make it a no-op instead of crashing
if (!mwLayout)
return;
if (mode == EndDragMode::Abort || !mwLayout->plug(state->widgetItem)) {
if (hasFeature(this, QDockWidget::DockWidgetFloatable)) {
// This QDockWidget will now stay in the floating state.

View File

@ -49,7 +49,7 @@ public:
, useUnifiedToolBar(false)
#endif
{ }
QMainWindowLayout *layout;
QPointer<QMainWindowLayout> layout;
QSize iconSize;
bool explicitIconSize;
Qt::ToolButtonStyle toolButtonStyle;
@ -60,7 +60,7 @@ public:
static inline QMainWindowLayout *mainWindowLayout(const QMainWindow *mainWindow)
{
return mainWindow ? mainWindow->d_func()->layout : static_cast<QMainWindowLayout *>(nullptr);
return mainWindow ? mainWindow->d_func()->layout.data() : static_cast<QMainWindowLayout *>(nullptr);
}
};