Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-43623

Use after free in QXcbShmImage::destroy()

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • P2: Important
    • None
    • 5.3.2
    • QPA: X11/XCB
    • 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

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            paeglis Gatis Paeglis
            cschutijser Caspar Schutijser
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes