Details
-
Bug
-
Resolution: Done
-
P2: Important
-
None
-
5.3.2
-
None
-
OpenBSD amd64.
Description
I used some Qt 5 program and I can get it to crash in two ways on OpenBSD:
#0 0x000015912c2f66ea in kill () at <stdin>:2 #1 0x000015912c32fec9 in abort () at /usr/src/lib/libc/stdlib/abort.c:53 #2 0x000015912c32c5e0 in wrterror (msg=0x15912c4392f6 "bogus pointer (double free?)", p=0xdfdfdfdfdfdfdfdf) at /usr/src/lib/libc/stdlib/malloc.c:281 #3 0x000015912c32dade in free (ptr=0xdfdfdfdfdfdfdfdf) at /usr/src/lib/libc/stdlib/malloc.c:1282 #4 0x0000159114c510ed in QXcbShmImage::destroy() () from /usr/local/lib/qt5/plugins/platforms/libqxcb.so #5 0x0000159114c51994 in QXcbBackingStore::~QXcbBackingStore() () from /usr/local/lib/qt5/plugins/platforms/libqxcb.so #6 0x0000159114c519c9 in QXcbBackingStore::~QXcbBackingStore() () from /usr/local/lib/qt5/plugins/platforms/libqxcb.so #7 0x00001590c3d3464b in QBackingStore::~QBackingStore() () from /usr/local/lib/qt5/libQt5Gui.so.0.0 #8 0x00001590ee310962 in QWidgetPrivate::deleteTLSysExtra() () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #9 0x00001590ee3119f0 in QWidget::destroy(bool, bool) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #10 0x00001590ee2f2fb8 in QWidget::~QWidget() () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #11 0x00001590a7d92aac in Core::Internal::MainWindow::aboutPlugins() () from /home/caspar/src/qt-creator/lib/qtcreator/plugins/libCore.so #12 0x00001590a7ed5575 in Core::Internal::MainWindow::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) () from /home/caspar/src/qt-creator/lib/qtcreator/plugins/libCore.so #13 0x00001591050542b8 in QMetaObject::activate(QObject*, int, int, void**) () from /usr/local/lib/qt5/libQt5Core.so.0.0 #14 0x00001590ee2b0a40 in QAction::triggered(bool) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #15 0x00001591050542b8 in QMetaObject::activate(QObject*, int, int, void**) () from /usr/local/lib/qt5/libQt5Core.so.0.0 #16 0x00001590ee2b0a40 in QAction::triggered(bool) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #17 0x00001590ee2b3221 in QAction::activate(QAction::ActionEvent) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #18 0x00001590ee4351fa in QMenuPrivate::activateCausedStack(QList<QPointer<QWidget> > const&, QAction*, QAction::ActionEvent, bool) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #19 0x00001590ee43ab2c in QMenuPrivate::activateAction(QAction*, QAction::ActionEvent, bool) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #20 0x00001590ee43f00a in QMenu::mouseReleaseEvent(QMouseEvent*) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #21 0x00001590ee2f6719 in QWidget::event(QEvent*) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #22 0x00001590ee43f81b in QMenu::event(QEvent*) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #23 0x00001590ee2b872c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #24 0x00001590ee2be58f in QApplication::notify(QObject*, QEvent*) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #25 0x000015910502b3fd in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/local/lib/qt5/libQt5Core.so.0.0 #26 0x00001590ee2bc803 in QApplicationPrivate::sendMouseEvent(QWidget*, QMouseEvent*, QWidget*, QWidget*, QWidget**, QPointer<QWidget>&, bool) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #27 0x00001590ee314938 in QWidgetWindow::handleMouseEvent(QMouseEvent*) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #28 0x00001590ee316ee3 in QWidgetWindow::event(QEvent*) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #29 0x00001590ee2b872c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #30 0x00001590ee2bd9f0 in QApplication::notify(QObject*, QEvent*) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #31 0x000015910502b3fd in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/local/lib/qt5/libQt5Core.so.0.0 #32 0x00001590c3bda51e in QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent*) () from /usr/local/lib/qt5/libQt5Gui.so.0.0 #33 0x00001590c3bdbed5 in QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent*) () from /usr/local/lib/qt5/libQt5Gui.so.0.0 #34 0x00001590c3bc1b68 in QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/local/lib/qt5/libQt5Gui.so.0.0 #35 0x0000159114c63430 in userEventSourceDispatch(_GSource*, int (*)(void*), void*) () from /usr/local/lib/qt5/plugins/platforms/libqxcb.so #36 0x0000159090eebf4f in g_main_context_dispatch () from /usr/local/lib/libglib-2.0.so.4200.0 #37 0x0000159090eedf9e in g_main_context_iterate () from /usr/local/lib/libglib-2.0.so.4200.0 #38 0x0000159090eee077 in g_main_context_iteration () from /usr/local/lib/libglib-2.0.so.4200.0 #39 0x000015910507b7b3 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/local/lib/qt5/libQt5Core.so.0.0 #40 0x0000159105029ffb in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/local/lib/qt5/libQt5Core.so.0.0 #41 0x0000159105030bf8 in QCoreApplication::exec() () from /usr/local/lib/qt5/libQt5Core.so.0.0 #42 0x0000158e7f50e5c2 in main ()
and
#0 0x00000e6cb94ba6ea in kill () at <stdin>:2 #1 0x00000e6cb94f3ec9 in abort () at /usr/src/lib/libc/stdlib/abort.c:53 #2 0x00000e6cb94f05e0 in wrterror (msg=0xe6cb95fd2f6 "bogus pointer (double free?)", p=0xdfdfdfdfdfdfdfdf) at /usr/src/lib/libc/stdlib/malloc.c:281 #3 0x00000e6cb94f1ade in free (ptr=0xdfdfdfdfdfdfdfdf) at /usr/src/lib/libc/stdlib/malloc.c:1282 #4 0x00000e6c61c3c0ed in QXcbShmImage::destroy() () from /usr/local/lib/qt5/plugins/platforms/libqxcb.so #5 0x00000e6c61c3ceff in QXcbBackingStore::resize(QSize const&, QRegion const&) () from /usr/local/lib/qt5/plugins/platforms/libqxcb.so #6 0x00000e6c9d341296 in QWidgetBackingStore::doSync() () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #7 0x00000e6c9d342170 in QWidgetBackingStore::sync() () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #8 0x00000e6c9d36323d in QWidgetPrivate::syncBackingStore() () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #9 0x00000e6c9d3733fe in QWidget::event(QEvent*) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #10 0x00000e6c9d33572c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #11 0x00000e6c9d33a9f0 in QApplication::notify(QObject*, QEvent*) () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #12 0x00000e6c28ace3fd in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/local/lib/qt5/libQt5Core.so.0.0 #13 0x00000e6c28ad0867 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/local/lib/qt5/libQt5Core.so.0.0 #14 0x00000e6c28b1eb23 in postEventSourceDispatch(_GSource*, int (*)(void*), void*) () from /usr/local/lib/qt5/libQt5Core.so.0.0 #15 0x00000e6c92ad9f4f in g_main_context_dispatch () from /usr/local/lib/libglib-2.0.so.4200.0 #16 0x00000e6c92adbf9e in g_main_context_iterate () from /usr/local/lib/libglib-2.0.so.4200.0 #17 0x00000e6c92adc077 in g_main_context_iteration () from /usr/local/lib/libglib-2.0.so.4200.0 #18 0x00000e6c28b1e7b3 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/local/lib/qt5/libQt5Core.so.0.0 #19 0x00000e6c28accffb in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/local/lib/qt5/libQt5Core.so.0.0 #20 0x00000e6c9d536f59 in QDialog::exec() () from /usr/local/lib/qt5/libQt5Widgets.so.0.0 #21 0x00000e6cd97ac35a in CMakeProjectManager::Internal::CMakeProject::fromMap(QMap<QString, QVariant> const&) () from /home/caspar/src/qt-creator/lib/qtcreator/plugins/libCMakeProjectManager.so #22 0x00000e6c614a8f82 in ProjectExplorer::Project::restoreSettings() () from /home/caspar/src/qt-creator/lib/qtcreator/plugins/libProjectExplorer.so #23 0x00000e6c61405e4e in ProjectExplorer::ProjectExplorerPlugin::openProjects(QStringList const&, QString*) () from /home/caspar/src/qt-creator/lib/qtcreator/plugins/libProjectExplorer.so #24 0x00000e6c61409eed in ProjectExplorer::ProjectExplorerPlugin::openProject(QString const&, QString*) () from /home/caspar/src/qt-creator/lib/qtcreator/plugins/libProjectExplorer.so #25 0x00000e6c6140a30f in ProjectExplorer::ProjectExplorerPlugin::openProjectWelcomePage(QString const&) () from /home/caspar/src/qt-creator/lib/qtcreator/plugins/libProjectExplorer.so #26 0x00000e6c28af72b8 in QMetaObject::activate(QObject*, int, int, void**) () from /usr/local/lib/qt5/libQt5Core.so.0.0 #27 0x00000e6c615a0d82 in ProjectExplorer::Internal::ProjectWelcomePage::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) () from /home/caspar/src/qt-creator/lib/qtcreator/plugins/libProjectExplorer.so #28 0x00000e6c615a1033 in ProjectExplorer::Internal::ProjectWelcomePage::qt_metacall(QMetaObject::Call, int, void**) () from /home/caspar/src/qt-creator/lib/qtcreator/plugins/libProjectExplorer.so #29 0x00000e6c741f7e81 in CallMethod(QObject*, int, int, int, int*, QV8Engine*, QV4::CallData*) () from /usr/local/lib/qt5/libQt5Qml.so.0.0 #30 0x00000e6c741fada2 in CallPrecise(QObject*, QQmlPropertyData const&, QV8Engine*, QV4::CallData*) () from /usr/local/lib/qt5/libQt5Qml.so.0.0 #31 0x00000e6c741fb430 in QV4::QObjectMethod::callInternal(QV4::CallData*) () from /usr/local/lib/qt5/libQt5Qml.so.0.0 #32 0x00000e6c74204e94 in QV4::Runtime::callProperty(QV4::ExecutionContext*, QV4::StringRef, QV4::CallDataRef) () from /usr/local/lib/qt5/libQt5Qml.so.0.0 #33 0x00000e6c01d6fa71 in ?? () #34 0x0000000000000000 in ?? ()
I started looking into QXcbShmImage::destroy() in the qt5/qtbase/src/plugins/platforms/xcb/qxcbbackingstore.cpp file. To me it seems there is a use after free:
150 void QXcbShmImage::destroy() 151 { 152 const int segmentSize = m_xcb_image ? (m_xcb_image->stride * m_xcb_image->height) : 0; 153 if (segmentSize && m_shm_info.shmaddr) 154 Q_XCB_CALL(xcb_shm_detach(xcb_connection(), m_shm_info.shmseg)); 155 156 xcb_image_destroy(m_xcb_image); 157 158 if (segmentSize) { 159 if (m_shm_info.shmaddr) { 160 shmdt(m_shm_info.shmaddr); 161 shmctl(m_shm_info.shmid, IPC_RMID, 0); 162 } else { 163 free(m_xcb_image->data); 164 } 165 } 166 167 if (m_gc) 168 Q_XCB_CALL(xcb_free_gc(xcb_connection(), m_gc)); 169 }
m_xcb_image is freed on line 156 (because that is what xcb_image_destroy() does) and then on line 163 it is used again.
An untested patch is attached. I don't know the code at all so it might be wrong but it will at least fix this problem.
Attachments
For Gerrit Dashboard: QTBUG-43623 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
103063,2 | Fix use-after-free bug | 5.4 | qt/qtbase | Status: MERGED | +2 | 0 |