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

heap-use-after-free in QTest::ignoreMessage

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P2: Important
    • None
    • 5.15.2, 6.3.1
    • Testing: qtestlib
    • None
    • d1dd9442392f3a1ab90a081bc58a84444a7a64c6

    Description

      Hi,
      I get a strange and flaky crash with the address sanitizer enabled. I don't see any mistake in my code here. It seems that the QTest::ignoreMessage call with qDebug will crash with different threads. The unit tests add some QTest::ignoreMessage in the main thread. Some logging will happen in main thread and also a spawned thread will log something. Sometimes it crashes if the separated thread will log something. Looks like handleIgnoredMessage of qtestlog is not thread-safe.

      I get this stacktrace. Used Qt 6.3.1 - but it crashes also with Qt 5.15.

      INFO   : test_UIPlugInAutomatic::insertNoCard() QVERIFY(context->isWorkflowKilled())
         Loc: [/.../test_UIPlugInAutomatic.cpp(186)]
      ==120169==ERROR: AddressSanitizer: heap-use-after-free on address 0x604000026238 at pc 0x7f61f021633d bp 0x7f61e31fb520 sp 0x7f61e31fb510
      READ of size 8 at 0x604000026238 thread T3 (ReaderManagerTh)
          #0 0x7f61f021633c in handleIgnoredMessage /.../src/qt/qtbase/src/testlib/qtestlog.cpp:206
          #1 0x7f61f0218f8a in messageHandler /.../src/qt/qtbase/src/testlib/qtestlog.cpp:247
          #2 0x7f61e976d0c4 in qt_message_print /.../src/qt/qtbase/src/corelib/global/qlogging.cpp:1837
          #3 0x7f61e976d311 in qt_message_output(QtMsgType, QMessageLogContext const&, QString const&) /.../src/qt/qtbase/src/corelib/global/qlogging.cpp:1888
          #4 0x7f61e979c2fc in QDebug::~QDebug() /.../src/qt/qtbase/src/corelib/io/qdebug.cpp:202
          #5 0x7f61ef50304f in company::ReaderManagerWorker::callOnPlugIn(company::EnumReaderManagerPlugInType::ReaderManagerPlugInType, std::function<void (company::ReaderManagerPlugIn*)> const&, char const*) /.../ReaderManagerWorker.cpp:131
          #6 0x7f61ef505604 in company::ReaderManagerWorker::startScan(company::EnumReaderManagerPlugInType::ReaderManagerPlugInType, bool) /.../ReaderManagerWorker.cpp:177
          #7 0x7f61ef4a2c9f in operator() /.../ReaderManager.cpp:185
          #8 0x7f61ef4ac6aa in call /.../dist/include/QtCore/qobjectdefs_impl.h:163
          #9 0x7f61ef4ac0a5 in call<QtPrivate::List<>, void> /.../dist/include/QtCore/qobjectdefs_impl.h:277
          #10 0x7f61ef4aba73 in impl /.../dist/include/QtCore/qobjectdefs_impl.h:444
          #11 0x7f61e998f1e3 in QtPrivate::QSlotObjectBase::call(QObject*, void**) /.../src/qt/qtbase/src/corelib/kernel/qobjectdefs_impl.h:399
          #12 0x7f61e998f1e3 in QMetaCallEvent::placeMetaCall(QObject*) /.../src/qt/qtbase/src/corelib/kernel/qobject.cpp:624
          #13 0x7f61e99a01ea in QObject::event(QEvent*) /.../src/qt/qtbase/src/corelib/kernel/qobject.cpp:1356
          #14 0x7f61e98b5d76 in QCoreApplicationPrivate::notify_helper(QObject*, QEvent*) /.../src/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1234
          #15 0x7f61e98b603a in doNotify /.../src/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1163
          #16 0x7f61e98b60d6 in QCoreApplication::notify(QObject*, QEvent*) /.../src/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1146
          #17 0x7f61e98b63a4 in QCoreApplication::notifyInternal2(QObject*, QEvent*) /.../src/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1067
          #18 0x7f61e98b6528 in QCoreApplication::sendEvent(QObject*, QEvent*) /.../src/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1483
          #19 0x7f61e98b8c1d in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) /.../src/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1845
          #20 0x7f61e98b8f30 in QCoreApplication::sendPostedEvents(QObject*, int) /.../src/qt/qtbase/src/corelib/kernel/qcoreapplication.cpp:1704
          #21 0x7f61e9ff16d3 in postEventSourceDispatch /.../src/qt/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:279
          #22 0x7f61e9517c6a in g_main_context_dispatch (/usr/lib/libglib-2.0.so.0+0x54c6a)
          #23 0x7f61e956e000  (/usr/lib/libglib-2.0.so.0+0xab000)
          #24 0x7f61e9515391 in g_main_context_iteration (/usr/lib/libglib-2.0.so.0+0x52391)
          #25 0x7f61e9fefa35 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) /.../src/qt/qtbase/src/corelib/kernel/qeventdispatcher_glib.cpp:429
          #26 0x7f61e98d5971 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) /.../src/qt/qtbase/src/corelib/kernel/qeventloop.cpp:136
          #27 0x7f61e98d6f27 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) /.../src/qt/qtbase/src/corelib/kernel/qeventloop.cpp:218
          #28 0x7f61e9bde317 in QThread::exec() /.../src/qt/qtbase/src/corelib/thread/qthread.cpp:553
          #29 0x7f61e9bde416 in QThread::run() /.../src/qt/qtbase/src/corelib/thread/qthread.cpp:622
          #30 0x7f61e9cfeba9 in operator() /.../src/qt/qtbase/src/corelib/thread/qthread_unix.cpp:356
          #31 0x7f61e9cfefa8 in terminate_on_exception<QThreadPrivate::start(void*)::<lambda()> > /.../src/qt/qtbase/src/corelib/thread/qthread_unix.cpp:292
          #32 0x7f61e9cff135 in QThreadPrivate::start(void*) /.../src/qt/qtbase/src/corelib/thread/qthread_unix.cpp:315
          #33 0x7f61e808c54c  (/usr/lib/libc.so.6+0x8c54c)
          #34 0x7f61e8111873 in clone (/usr/lib/libc.so.6+0x111873)
      
      0x604000026238 is located 40 bytes inside of 48-byte region [0x604000026210,0x604000026240)
      freed by thread T0 here:
          #0 0x7f61f72c178a in operator delete(void*, unsigned long) /usr/src/debug/gcc/libsanitizer/asan/asan_new_delete.cpp:164
          #1 0x7f61f02162b7 in handleIgnoredMessage /.../src/qt/qtbase/src/testlib/qtestlog.cpp:201
          #2 0x7f61f0218f8a in messageHandler /.../src/qt/qtbase/src/testlib/qtestlog.cpp:247
          #3 0x7f61e976d0c4 in qt_message_print /.../src/qt/qtbase/src/corelib/global/qlogging.cpp:1837
          #4 0x7f61e976d311 in qt_message_output(QtMsgType, QMessageLogContext const&, QString const&) /.../src/qt/qtbase/src/corelib/global/qlogging.cpp:1888
          #5 0x7f61e979c2fc in QDebug::~QDebug() /.../src/qt/qtbase/src/corelib/io/qdebug.cpp:202
          #6 0x7f61f79a457d in company::UIPlugInAutomatic::handleInsertCard() /.../UIPlugInAutomatic.cpp:129
          #7 0x7f61f79a36ab in company::UIPlugInAutomatic::onStateChanged(QString const&) /.../UIPlugInAutomatic.cpp:86
          #8 0x7f61f79bd8d1 in QtPrivate::FunctorCall<QtPrivate::IndexesList<0>, QtPrivate::List<QString const&>, void, void (company::UIPlugInAutomatic::*)(QString const&)>::call(void (company::UIPlugInAutomatic::*)(QString const&), company::UIPlugInAutomatic*, void**) /.../dist/include/QtCore/qobjectdefs_impl.h:171
          #9 0x7f61f79bc668 in void QtPrivate::FunctionPointer<void (company::UIPlugInAutomatic::*)(QString const&)>::call<QtPrivate::List<QString const&>, void>(void (company::UIPlugInAutomatic::*)(QString const&), company::UIPlugInAutomatic*, void**) /.../dist/include/QtCore/qobjectdefs_impl.h:208
          #10 0x7f61f79b7544 in QtPrivate::QSlotObject<void (company::UIPlugInAutomatic::*)(QString const&), QtPrivate::List<QString const&>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) /.../dist/include/QtCore/qobjectdefs_impl.h:419
          #11 0x7f61e99b91c3 in QtPrivate::QSlotObjectBase::call(QObject*, void**) /.../src/qt/qtbase/src/corelib/kernel/qobjectdefs_impl.h:399
          #12 0x7f61e99b91c3 in void doActivate<false>(QObject*, int, void**) /.../src/qt/qtbase/src/corelib/kernel/qobject.cpp:3921
          #13 0x7f61e99a0ce5 in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) /.../src/qt/qtbase/src/corelib/kernel/qobject.cpp:3981
          #14 0x7f61f196e30b in company::WorkflowContext::fireStateChanged(QString const&) /.../AusweisAppWorkflows_autogen/3YXCLTWOAO/moc_WorkflowContext.cpp:415
          #15 0x7f61f1a6b7f9 in company::WorkflowContext::setCurrentState(QString const&) /.../WorkflowContext.cpp:164
          #16 0x55588ad5fccc in test_UIPlugInAutomatic::insertNoCard() /.../test_UIPlugInAutomatic.cpp:185
          #17 0x55588ad505ad in test_UIPlugInAutomatic::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /.../include/test_UIPlugInAutomatic.moc:206
          #18 0x7f61e98ea861 in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const /.../src/qt/qtbase/src/corelib/kernel/qmetaobject.cpp:2391
          #19 0x7f61f01f9980 in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const /.../src/qt/qtbase/src/corelib/kernel/qmetaobject.h:126
          #20 0x7f61f01f0d13 in QTest::TestMethods::invokeTestOnData(int) const /.../src/qt/qtbase/src/testlib/qtestcase.cpp:1057
          #21 0x7f61f01f38a1 in QTest::TestMethods::invokeTest(int, QLatin1String, QTest::WatchDog*) const /.../src/qt/qtbase/src/testlib/qtestcase.cpp:1309
          #22 0x7f61f01f513e in QTest::TestMethods::invokeTests(QObject*) const /.../src/qt/qtbase/src/testlib/qtestcase.cpp:1658
          #23 0x7f61f01f68ed in QTest::qRun() /.../src/qt/qtbase/src/testlib/qtestcase.cpp:2124
          #24 0x7f61f01f6e4f in QTest::qExec(QObject*, int, char**) /.../src/qt/qtbase/src/testlib/qtestcase.cpp:2026
          #25 0x55588ad4f26c in main /.../test_UIPlugInAutomatic.cpp:385
          #26 0x7f61e802928f  (/usr/lib/libc.so.6+0x2928f)
      
      previously allocated by thread T0 here:
          #0 0x7f61f72c0672 in operator new(unsigned long) /usr/src/debug/gcc/libsanitizer/asan/asan_new_delete.cpp:95
          #1 0x7f61f021aa20 in QTest::IgnoreResultList::append(QTest::IgnoreResultList*&, QtMsgType, QVariant const&) /.../src/qt/qtbase/src/testlib/qtestlog.cpp:131
          #2 0x7f61f0216527 in QTestLog::ignoreMessage(QtMsgType, char const*) /.../src/qt/qtbase/src/testlib/qtestlog.cpp:574
          #3 0x7f61f01e1642 in QTest::ignoreMessage(QtMsgType, char const*) /.../src/qt/qtbase/src/testlib/qtestcase.cpp:2294
          #4 0x55588ad5fa9d in test_UIPlugInAutomatic::insertNoCard() /.../test_UIPlugInAutomatic.cpp:183
          #5 0x55588ad505ad in test_UIPlugInAutomatic::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /.../include/test_UIPlugInAutomatic.moc:206
          #6 0x7f61e98ea861 in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const /.../src/qt/qtbase/src/corelib/kernel/qmetaobject.cpp:2391
          #7 0x7f61f01f9980 in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const /.../src/qt/qtbase/src/corelib/kernel/qmetaobject.h:126
          #8 0x7f61f01f0d13 in QTest::TestMethods::invokeTestOnData(int) const /.../src/qt/qtbase/src/testlib/qtestcase.cpp:1057
          #9 0x7f61f01f38a1 in QTest::TestMethods::invokeTest(int, QLatin1String, QTest::WatchDog*) const /.../src/qt/qtbase/src/testlib/qtestcase.cpp:1309
          #10 0x7f61f01f513e in QTest::TestMethods::invokeTests(QObject*) const /.../src/qt/qtbase/src/testlib/qtestcase.cpp:1658
          #11 0x7f61f01f68ed in QTest::qRun() /.../src/qt/qtbase/src/testlib/qtestcase.cpp:2124
          #12 0x7f61f01f6e4f in QTest::qExec(QObject*, int, char**) /.../src/qt/qtbase/src/testlib/qtestcase.cpp:2026
          #13 0x55588ad4f26c in main /.../test_UIPlugInAutomatic.cpp:385
          #14 0x7f61e802928f  (/usr/lib/libc.so.6+0x2928f)
      
      Thread T3 (ReaderManagerTh) created by T0 here:
          #0 0x7f61f7264207 in __interceptor_pthread_create /usr/src/debug/gcc/libsanitizer/asan/asan_interceptors.cpp:207
          #1 0x7f61e9cfe0db in QThread::start(QThread::Priority) /.../src/qt/qtbase/src/corelib/thread/qthread_unix.cpp:719
          #2 0x7f61ef49fac8 in company::ReaderManager::init() /.../ReaderManager.cpp:97
          #3 0x55588ad5b29c in test_UIPlugInAutomatic::initTestCase() /.../test_UIPlugInAutomatic.cpp:65
          #4 0x55588ad4fdad in test_UIPlugInAutomatic::qt_static_metacall(QObject*, QMetaObject::Call, int, void**) /.../include/test_UIPlugInAutomatic.moc:198
          #5 0x7f61e98ea861 in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericReturnArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const /.../src/qt/qtbase/src/corelib/kernel/qmetaobject.cpp:2391
          #6 0x7f61f01f9980 in QMetaMethod::invoke(QObject*, Qt::ConnectionType, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument, QGenericArgument) const /.../src/qt/qtbase/src/corelib/kernel/qmetaobject.h:126
          #7 0x7f61f01f4c58 in QTest::TestMethods::invokeTests(QObject*) const /.../src/qt/qtbase/src/testlib/qtestcase.cpp:1645
          #8 0x7f61f01f68ed in QTest::qRun() /.../src/qt/qtbase/src/testlib/qtestcase.cpp:2124
          #9 0x7f61f01f6e4f in QTest::qExec(QObject*, int, char**) /.../src/qt/qtbase/src/testlib/qtestcase.cpp:2026
          #10 0x55588ad4f26c in main /.../test_UIPlugInAutomatic.cpp:385
          #11 0x7f61e802928f  (/usr/lib/libc.so.6+0x2928f)
      
      SUMMARY: AddressSanitizer: heap-use-after-free /.../src/qt/qtbase/src/testlib/qtestlog.cpp:206 in handleIgnoredMessage
      Shadow bytes around the buggy address:
        0x0c087fffcbf0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c087fffcc00: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
        0x0c087fffcc10: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
        0x0c087fffcc20: fa fa fd fd fd fd fd fa fa fa fd fd fd fd fd fa
        0x0c087fffcc30: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fa
      =>0x0c087fffcc40: fa fa fd fd fd fd fd[fd]fa fa fd fd fd fd fd fd
        0x0c087fffcc50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c087fffcc60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c087fffcc70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c087fffcc80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
        0x0c087fffcc90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      Shadow byte legend (one shadow byte represents 8 application bytes):
        Addressable:           00
        Partially addressable: 01 02 03 04 05 06 07 
        Heap left redzone:       fa
        Freed heap region:       fd
        Stack left redzone:      f1
        Stack mid redzone:       f2
        Stack right redzone:     f3
        Stack after return:      f5
        Stack use after scope:   f8
        Global redzone:          f9
        Global init order:       f6
        Poisoned by user:        f7
        Container overflow:      fc
        Array cookie:            ac
        Intra object redzone:    bb
        ASan internal:           fe
        Left alloca redzone:     ca
        Right alloca redzone:    cb
      

       

      Attachments

        For Gerrit Dashboard: QTBUG-104840
        # Subject Branch Project Status CR V

        Activity

          People

            macadder Jason McDonald
            misery André Klitzing
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are 2 open Gerrit changes