Bug 420318 - ItemRetrievalRequest heap-use-after-free
Summary: ItemRetrievalRequest heap-use-after-free
Status: RESOLVED DUPLICATE of bug 408897
Alias: None
Product: Akonadi
Classification: Frameworks and Libraries
Component: server (show other bugs)
Version: unspecified
Platform: Compiled Sources Linux
: NOR normal
Target Milestone: ---
Assignee: kdepim bugs
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-04-19 21:43 UTC by Lukáš Karas
Modified: 2020-04-27 09:10 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Lukáš Karas 2020-04-19 21:43:15 UTC
Akonadi crash sometimes on my machine. To get better idea where the bug is, I build akonadi server with address sanitizer ( -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_CXX_FLAGS=-fsanitize=address ). It shows me heap-use-after-free: 

==772029==ERROR: AddressSanitizer: heap-use-after-free on address 0x604000272a90 at pc 0x55899a50df07 bp 0x7fd9cd9ef1c0 sp 0x7fd9cd9ef1b0
READ of size 8 at 0x604000272a90 thread T4 (ItemRetrievalMa)
    #0 0x55899a50df06 in QListData::begin() const /usr/include/x86_64-linux-gnu/qt5/QtCore/qlist.h:116
    #1 0x55899a5b1087 in QList<long long>::begin() const /usr/include/x86_64-linux-gnu/qt5/QtCore/qlist.h:325
    #2 0x55899a8aec12 in QDebug QtPrivate::printSequentialContainer<QList<long long> >(QDebug, char const*, QList<long long> const&) /usr/include/x86_64-linux-gnu/qt5/QtCore/qdebug.h:219
    #3 0x55899a8aaebb in QDebug operator<< <long long>(QDebug, QList<long long> const&) /usr/include/x86_64-linux-gnu/qt5/QtCore/qdebug.h:238
    #4 0x55899a8b99e2 in Akonadi::Server::ItemRetrievalJob::start() /home/karry/data/cecko/KDE/akonadi/src/server/storage/itemretrievaljob.cpp:47
    #5 0x55899a8a69fe in Akonadi::Server::ItemRetrievalManager::processRequest() /home/karry/data/cecko/KDE/akonadi/src/server/storage/itemretrievalmanager.cpp:164
    #6 0x55899a8b779c in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (Akonadi::Server::ItemRetrievalManager::*)()>::call(void (Akonadi::Server::ItemRetrievalManager::*)(), Akonadi::Server::ItemRetrievalManager*, void**) /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:152
    #7 0x55899a8b5c84 in void QtPrivate::FunctionPointer<void (Akonadi::Server::ItemRetrievalManager::*)()>::call<QtPrivate::List<>, void>(void (Akonadi::Server::ItemRetrievalManager::*)(), Akonadi::Server::ItemRetrievalManager*, void**) /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:185
    #8 0x55899a8b385d in QtPrivate::QSlotObject<void (Akonadi::Server::ItemRetrievalManager::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) /usr/include/x86_64-linux-gnu/qt5/QtCore/qobjectdefs_impl.h:414
    #9 0x7fd9d76e0d59 in QObject::event(QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2b2d59)
    #10 0x7fd9d76b4916 in QCoreApplication::notifyInternal2(QObject*, QEvent*) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x286916)
    #11 0x7fd9d76b75b7 in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2895b7)
    #12 0x7fd9d770cf66  (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2def66)
    #13 0x7fd9d6068fbc in g_main_context_dispatch (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51fbc)
    #14 0x7fd9d606923f  (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5223f)
    #15 0x7fd9d60692e2 in g_main_context_iteration (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x522e2)
    #16 0x7fd9d770c564 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2de564)
    #17 0x7fd9d76b34da in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2854da)
    #18 0x7fd9d74eb784 in QThread::exec() (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0xbd784)
    #19 0x7fd9d74ec9d1  (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0xbe9d1)
    #20 0x7fd9d7013608 in start_thread /build/glibc-aevPTw/glibc-2.31/nptl/pthread_create.c:477
    #21 0x7fd9d7162102 in __clone (/lib/x86_64-linux-gnu/libc.so.6+0x122102)

0x604000272a90 is located 0 bytes inside of 40-byte region [0x604000272a90,0x604000272ab8)
freed by thread T12 (0x6110000c1ec0-) here:
    #0 0x7fd9d8078025 in operator delete(void*, unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x111025)
    #1 0x55899a8a22ee in std::default_delete<Akonadi::Server::ItemRetrievalRequest>::operator()(Akonadi::Server::ItemRetrievalRequest*) const (/usr/bin/akonadiserver+0x4692ee)
    #2 0x55899a8a0ea2 in std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> >::~unique_ptr() /usr/include/c++/9/bits/unique_ptr.h:292
    #3 0x55899a8a09b5 in void std::_Destroy<std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> > >(std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> >*) /usr/include/c++/9/bits/stl_construct.h:98
    #4 0x55899a89e842 in void std::_Destroy_aux<false>::__destroy<std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> >*>(std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> >*, std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> >*) /usr/include/c++/9/bits/stl_construct.h:108
    #5 0x55899a89c583 in void std::_Destroy<std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> >*>(std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> >*, std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> >*) /usr/include/c++/9/bits/stl_construct.h:137
    #6 0x55899a8991cc in void std::_Destroy<std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> >*, std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> > >(std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> >*, std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> >*, std::allocator<std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> > >&) /usr/include/c++/9/bits/stl_construct.h:206
    #7 0x55899a8966e3 in std::vector<std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> >, std::allocator<std::unique_ptr<Akonadi::Server::ItemRetrievalRequest, std::default_delete<Akonadi::Server::ItemRetrievalRequest> > > >::~vector() /usr/include/c++/9/bits/stl_vector.h:677
    #8 0x55899a890ca8 in Akonadi::Server::ItemRetriever::exec() /home/karry/data/cecko/KDE/akonadi/src/server/storage/itemretriever.cpp:231
    #9 0x55899a5dc93a in Akonadi::Server::ItemFetchHelper::fetchItems(std::function<void (Akonadi::Protocol::FetchItemsResponse&&)>&&) /home/karry/data/cecko/KDE/akonadi/src/server/handler/itemfetchhelper.cpp:370
    #10 0x55899a5d279e in Akonadi::Server::ItemFetchHandler::parseStream() /home/karry/data/cecko/KDE/akonadi/src/server/handler/itemfetchhandler.cpp:50
    #11 0x55899a527314 in Akonadi::Server::Connection::parseStream(QSharedPointer<Akonadi::Protocol::Command> const&) /home/karry/data/cecko/KDE/akonadi/src/server/connection.cpp:183
    #12 0x55899a52771f in operator() /home/karry/data/cecko/KDE/akonadi/src/server/connection.cpp:274
    #13 0x55899a52d55b in callFunc<Akonadi::Server::Connection::handleIncomingData()::<lambda()>&> /home/karry/data/cecko/KDE/akonadi/src/server/storage/dbdeadlockcatcher.h:47
    #14 0x55899a52d537 in DbDeadlockCatcher<Akonadi::Server::Connection::handleIncomingData()::<lambda()> > /home/karry/data/cecko/KDE/akonadi/src/server/storage/dbdeadlockcatcher.h:40
    #15 0x55899a528b8f in Akonadi::Server::Connection::handleIncomingData() /home/karry/data/cecko/KDE/akonadi/src/server/connection.cpp:274
    #16 0x55899a536926 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (Akonadi::Server::Connection::*)()>::call(void (Akonadi::Server::Connection::*)(), Akonadi::Server::Connection*, void**) (/usr/bin/akonadiserver+0xfd926)
    #17 0x55899a535ec2 in void QtPrivate::FunctionPointer<void (Akonadi::Server::Connection::*)()>::call<QtPrivate::List<>, void>(void (Akonadi::Server::Connection::*)(), Akonadi::Server::Connection*, void**) (/usr/bin/akonadiserver+0xfcec2)
    #18 0x55899a534f07 in QtPrivate::QSlotObject<void (Akonadi::Server::Connection::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (/usr/bin/akonadiserver+0xfbf07)
    #19 0x7fd9d76ed5b5  (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2bf5b5)

previously allocated by thread T12 (0x6110000c1ec0-) here:
    #0 0x7fd9d8076947 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x10f947)
    #1 0x55899a88f5c6 in Akonadi::Server::ItemRetriever::exec() /home/karry/data/cecko/KDE/akonadi/src/server/storage/itemretriever.cpp:276
    #2 0x55899a5dc93a in Akonadi::Server::ItemFetchHelper::fetchItems(std::function<void (Akonadi::Protocol::FetchItemsResponse&&)>&&) /home/karry/data/cecko/KDE/akonadi/src/server/handler/itemfetchhelper.cpp:370
    #3 0x55899a5d279e in Akonadi::Server::ItemFetchHandler::parseStream() /home/karry/data/cecko/KDE/akonadi/src/server/handler/itemfetchhandler.cpp:50
    #4 0x55899a527314 in Akonadi::Server::Connection::parseStream(QSharedPointer<Akonadi::Protocol::Command> const&) /home/karry/data/cecko/KDE/akonadi/src/server/connection.cpp:183
    #5 0x55899a52771f in operator() /home/karry/data/cecko/KDE/akonadi/src/server/connection.cpp:274
    #6 0x55899a52d55b in callFunc<Akonadi::Server::Connection::handleIncomingData()::<lambda()>&> /home/karry/data/cecko/KDE/akonadi/src/server/storage/dbdeadlockcatcher.h:47
    #7 0x55899a52d537 in DbDeadlockCatcher<Akonadi::Server::Connection::handleIncomingData()::<lambda()> > /home/karry/data/cecko/KDE/akonadi/src/server/storage/dbdeadlockcatcher.h:40
    #8 0x55899a528b8f in Akonadi::Server::Connection::handleIncomingData() /home/karry/data/cecko/KDE/akonadi/src/server/connection.cpp:274
    #9 0x55899a536926 in QtPrivate::FunctorCall<QtPrivate::IndexesList<>, QtPrivate::List<>, void, void (Akonadi::Server::Connection::*)()>::call(void (Akonadi::Server::Connection::*)(), Akonadi::Server::Connection*, void**) (/usr/bin/akonadiserver+0xfd926)
    #10 0x55899a535ec2 in void QtPrivate::FunctionPointer<void (Akonadi::Server::Connection::*)()>::call<QtPrivate::List<>, void>(void (Akonadi::Server::Connection::*)(), Akonadi::Server::Connection*, void**) (/usr/bin/akonadiserver+0xfcec2)
    #11 0x55899a534f07 in QtPrivate::QSlotObject<void (Akonadi::Server::Connection::*)(), QtPrivate::List<>, void>::impl(int, QtPrivate::QSlotObjectBase*, QObject*, void**, bool*) (/usr/bin/akonadiserver+0xfbf07)
    #12 0x7fd9d76ed5b5  (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0x2bf5b5)

Thread T4 (ItemRetrievalMa) created by T0 here:
    #0 0x7fd9d7fa1805 in pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x3a805)
    #1 0x7fd9d74ec463 in QThread::start(QThread::Priority) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0xbe463)

Thread T12 (0x6110000c1ec0-) created by T0 here:
    #0 0x7fd9d7fa1805 in pthread_create (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x3a805)
    #1 0x7fd9d74ec463 in QThread::start(QThread::Priority) (/usr/lib/x86_64-linux-gnu/libQt5Core.so.5+0xbe463)

SUMMARY: AddressSanitizer: heap-use-after-free /usr/include/x86_64-linux-gnu/qt5/QtCore/qlist.h:116 in QListData::begin() const



Request ItemRetrievalRequest is created in unique_ptr at itemretriever.cpp:276, then its pointer is pass to ItemRetrievalManager::requestItemDelivery, this method takes ownership by documentation, but it is still owned by unique_ptr and instance is deleted when requests vector is deleted! It seems that ItemRetrievalManager::processRequest is called after and it touch deleted object. Question is how that live cycle issue should be solved? Using shared pointer? Remove ownership from unique_ptr?

SOFTWARE/OS VERSIONS

Akonadi build from git branch "release/20.04"
Qt Version: 5.12.8
Comment 1 Daniel Vrátil 2020-04-27 09:10:37 UTC
Fixed by ItemRetrievalRequest/ItemRetriever refactoring.

*** This bug has been marked as a duplicate of bug 408897 ***