Details
-
Bug
-
Resolution: Done
-
P1: Critical
-
None
-
5.12
-
None
Description
The use-after-free is triggered in tst_lupdate::good(proparsingpaths).
ProFileEvaluator::absoluteFileValues creates the string absEl inside the mail foreach loop, with the last change on line 145 (absEl = QDir::cleanPath....). Then in line 149 its rawData gets used to create absDir, which gets passed into QMakeVfs on the next line. This function in turn will put the string into the m_files hash.
However, the backing data (absEl on line 127) is freed on the next iteration, so subsequent hash accesses result in the use-after-free.
ASAN report:
================================================================= ==44232==ERROR: AddressSanitizer: heap-use-after-free on address 0x6110000c9818 at pc 0x000100a6bfd7 bp 0x7ffeefbf8a10 sp 0x7ffeefbf8a08 READ of size 16 at 0x6110000c9818 thread T0 #0 0x100a6bfd6 in QtNS::ucstrncmp(QtNS::QChar const*, QtNS::QChar const*, unsigned long) qstring.cpp:867 #1 0x100a6b640 in QtNS::ucstrcmp(QtNS::QChar const*, unsigned long, QtNS::QChar const*, unsigned long) qstring.cpp:1109 #2 0x100a121cb in QtNS::qt_compare_strings(QtNS::QStringView, QtNS::QStringView, QtNS::Qt::CaseSensitivity) qstring.cpp:1123 #3 0x100a22fb1 in QtNS::operator==(QtNS::QString const&, QtNS::QString const&) qstring.cpp:3329 #4 0x10002870c in QtNS::QHashNode<QtNS::QString, QtNS::QString>::same_key(unsigned int, QtNS::QString const&) const qhash.h:158 #5 0x1000285e9 in QtNS::QHash<QtNS::QString, QtNS::QString>::findNode(QtNS::QString const&, unsigned int) const qhash.h:919 #6 0x100028039 in QtNS::QHash<QtNS::QString, QtNS::QString>::findNode(QtNS::QString const&, unsigned int*) const qhash.h:938 #7 0x10009e178 in QtNS::QHash<QtNS::QString, QtNS::QString>::constFind(QtNS::QString const&) const qhash.h:895 #8 0x10009e455 in QtNS::QMakeVfs::exists(QtNS::QString const&) qmakevfs.cpp:153 #9 0x10014c8fe in QtNS::ProFileEvaluator::absoluteFileValues(QtNS::QString const&, QtNS::QString const&, QtNS::QStringList const&, QtNS::ProFile const*) const profileevaluator.cpp:150 #10 0x100173d01 in getSources(char const*, char const*, QtNS::QStringList const&, QtNS::QString const&, QtNS::ProFileEvaluator const&) main.cpp:468 #11 0x100171514 in getSources(QtNS::ProFileEvaluator const&, QtNS::QString const&, QtNS::QStringList const&, QtNS::QMakeVfs*) main.cpp:482 #12 0x10016f851 in processProject(bool, QtNS::QString const&, QtNS::ProFileGlobals*, QtNS::QMakeVfs*, QtNS::QMakeParser*, QtNS::ProFileEvaluator&, QtNS::QFlags<QtNS::UpdateOption>, QtNS::QString const&, QtNS::QString const&, QtNS::Translator*, bool*) main.cpp:679 #13 0x1001680e0 in processProjects(bool, bool, QtNS::QStringList const&, QtNS::QHash<QtNS::QString, QtNS::QString> const&, QtNS::ProFileGlobals*, QtNS::QMakeVfs*, QtNS::QMakeParser*, QtNS::QFlags<QtNS::UpdateOption>, QtNS::QString const&, QtNS::QString const&, QtNS::Translator*, bool*) main.cpp:750 #14 0x10015e359 in main main.cpp:1144 #15 0x7fff66bbb014 in start (libdyld.dylib:x86_64+0x1014) 0x6110000c9818 is located 24 bytes inside of 224-byte region [0x6110000c9800,0x6110000c98e0) freed by thread T0 here: #0 0x10225afdd in wrap_free (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x56fdd) #1 0x10080f8a1 in QtNS::QArrayData::deallocate(QtNS::QArrayData*, unsigned long, unsigned long) qarraydata.cpp:167 #2 0x100005e72 in QtNS::QTypedArrayData<unsigned short>::deallocate(QtNS::QArrayData*) qarraydata.h:239 #3 0x10022a9a6 in QtNS::QString::~QString() qstring.h:1132 #4 0x1001e9074 in QtNS::QString::~QString() qstring.h:1132 #5 0x10014d385 in QtNS::ProFileEvaluator::absoluteFileValues(QtNS::QString const&, QtNS::QString const&, QtNS::QStringList const&, QtNS::ProFile const*) const profileevaluator.cpp:163 #6 0x100173d01 in getSources(char const*, char const*, QtNS::QStringList const&, QtNS::QString const&, QtNS::ProFileEvaluator const&) main.cpp:468 #7 0x100171514 in getSources(QtNS::ProFileEvaluator const&, QtNS::QString const&, QtNS::QStringList const&, QtNS::QMakeVfs*) main.cpp:482 #8 0x10016f851 in processProject(bool, QtNS::QString const&, QtNS::ProFileGlobals*, QtNS::QMakeVfs*, QtNS::QMakeParser*, QtNS::ProFileEvaluator&, QtNS::QFlags<QtNS::UpdateOption>, QtNS::QString const&, QtNS::QString const&, QtNS::Translator*, bool*) main.cpp:679 #9 0x1001680e0 in processProjects(bool, bool, QtNS::QStringList const&, QtNS::QHash<QtNS::QString, QtNS::QString> const&, QtNS::ProFileGlobals*, QtNS::QMakeVfs*, QtNS::QMakeParser*, QtNS::QFlags<QtNS::UpdateOption>, QtNS::QString const&, QtNS::QString const&, QtNS::Translator*, bool*) main.cpp:750 #10 0x10015e359 in main main.cpp:1144 #11 0x7fff66bbb014 in start (libdyld.dylib:x86_64+0x1014) previously allocated by thread T0 here: #0 0x10225ae13 in wrap_malloc (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0x56e13) #1 0x10080e6a3 in QtNS::QArrayData::allocate(unsigned long, unsigned long, unsigned long, QtNS::QFlags<QtNS::QArrayData::AllocationOption>) qarraydata.cpp:118 #2 0x100a15346 in QtNS::QTypedArrayData<unsigned short>::allocate(unsigned long, QtNS::QFlags<QtNS::QArrayData::AllocationOption>) qarraydata.h:224 #3 0x100a15dde in QtNS::QString::QString(int, QtNS::Qt::Initialization) qstring.cpp:2117 #4 0x100a16010 in QtNS::QString::QString(int, QtNS::Qt::Initialization) qstring.cpp:2116 #5 0x10006d89c in QtNS::QString QtNS::QStringBuilder<QtNS::QStringBuilder<QtNS::QString, QtNS::QLatin1Char>, QtNS::QString>::convertTo<QtNS::QString>() const qstringbuilder.h:112 #6 0x100065b9b in QtNS::QStringBuilder<QtNS::QStringBuilder<QtNS::QString, QtNS::QLatin1Char>, QtNS::QString>::operator QtNS::QString() const qstringbuilder.h:131 #7 0x10014c6a9 in QtNS::ProFileEvaluator::absoluteFileValues(QtNS::QString const&, QtNS::QString const&, QtNS::QStringList const&, QtNS::ProFile const*) const profileevaluator.cpp:145 #8 0x100173d01 in getSources(char const*, char const*, QtNS::QStringList const&, QtNS::QString const&, QtNS::ProFileEvaluator const&) main.cpp:468 #9 0x100171514 in getSources(QtNS::ProFileEvaluator const&, QtNS::QString const&, QtNS::QStringList const&, QtNS::QMakeVfs*) main.cpp:482 #10 0x10016f851 in processProject(bool, QtNS::QString const&, QtNS::ProFileGlobals*, QtNS::QMakeVfs*, QtNS::QMakeParser*, QtNS::ProFileEvaluator&, QtNS::QFlags<QtNS::UpdateOption>, QtNS::QString const&, QtNS::QString const&, QtNS::Translator*, bool*) main.cpp:679 #11 0x1001680e0 in processProjects(bool, bool, QtNS::QStringList const&, QtNS::QHash<QtNS::QString, QtNS::QString> const&, QtNS::ProFileGlobals*, QtNS::QMakeVfs*, QtNS::QMakeParser*, QtNS::QFlags<QtNS::UpdateOption>, QtNS::QString const&, QtNS::QString const&, QtNS::Translator*, bool*) main.cpp:750 #12 0x10015e359 in main main.cpp:1144 #13 0x7fff66bbb014 in start (libdyld.dylib:x86_64+0x1014) SUMMARY: AddressSanitizer: heap-use-after-free qstring.cpp:867 in QtNS::ucstrncmp(QtNS::QChar const*, QtNS::QChar const*, unsigned long) Shadow bytes around the buggy address: 0x1c22000192b0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x1c22000192c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x1c22000192d0: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 0x1c22000192e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x1c22000192f0: 00 00 00 00 fa fa fa fa fa fa fa fa fa fa fa fa =>0x1c2200019300: fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd fd fd 0x1c2200019310: fd fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa 0x1c2200019320: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd 0x1c2200019330: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 0x1c2200019340: fd fd fd fd fd fa fa fa fa fa fa fa fa fa fa fa 0x1c2200019350: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd 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