Bug 463764

Summary: SIGSEGV in QArrayData::data (called via ThumbnailProvider::requestImage)
Product: [Applications] kdenlive Reporter: kdenlive-bug
Component: User Interface & MiscellaneousAssignee: Jean-Baptiste Mardelle <jb>
Status: RESOLVED FIXED    
Severity: normal    
Priority: NOR    
Version: 22.12.0   
Target Milestone: ---   
Platform: Other   
OS: OpenBSD   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description kdenlive-bug 2023-01-03 01:27:26 UTC
SUMMARY

Frequent crashes while editing a video project.

STEPS TO REPRODUCE

Unfortunately no specific reproducible instructions are known at the moment although normal use on OpenBSD-7.2-amd64-current reliably causes a core dump.

OBSERVED RESULT

SIGSEGV crash with this trace:

(gdb) bt
#0  0x000008bd4ce3004a in QArrayData::data() () from /usr/local/lib/qt5/./libQt5Core.so.4.0
#1  0x000008bd4ce42f9f in QTypedArrayData<unsigned short>::data() () from /usr/local/lib/qt5/./libQt5Core.so.4.0
#2  0x000008bd4cf0bc82 in QString::unicode() const () from /usr/local/lib/qt5/./libQt5Core.so.4.0
#3  0x000008bd4cf0a835 in qHash(QString const&, unsigned int) () from /usr/local/lib/qt5/./libQt5Core.so.4.0
#4  0x000008baf186a257 in ThumbnailCache::Cache_t::remove(QString const&) ()
#5  0x000008baf186a570 in ThumbnailCache::Cache_t::insert(QString const&, QImage const&, int) ()
#6  0x000008baf1868663 in ThumbnailCache::storeThumbnail(QString const&, int, QImage const&, bool) ()
#7  0x000008baf17daf1e in ThumbnailProvider::requestImage(QString const&, QSize*, QSize const&) ()
#8  0x000008bdda2bbde8 in QQuickPixmapReader::processJob(QQuickPixmapReply*, QUrl const&, QString const&, QQmlImageProviderBase::ImageType, QSharedPointer<QQuickImageProvider> const&) () from /usr/local/lib/qt5/./libQt5Quick.so.4.0
#9  0x000008bdda2baa63 in QQuickPixmapReader::processJobs() () from /usr/local/lib/qt5/./libQt5Quick.so.4.0
#10 0x000008bdda2ba316 in QQuickPixmapReaderThreadObject::event(QEvent*) () from /usr/local/lib/qt5/./libQt5Quick.so.4.0
#11 0x000008bd4952074a in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/local/lib/qt5/./libQt5Widgets.so.4.0
#12 0x000008bd49522423 in QApplication::notify(QObject*, QEvent*) () from /usr/local/lib/qt5/./libQt5Widgets.so.4.0
#13 0x000008bd4d186c72 in QCoreApplication::notifyInternal2(QObject*, QEvent*) () from /usr/local/lib/qt5/./libQt5Core.so.4.0
#14 0x000008bd4d187925 in QCoreApplication::sendEvent(QObject*, QEvent*) () from /usr/local/lib/qt5/./libQt5Core.so.4.0
#15 0x000008bd4d18867a in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) ()
   from /usr/local/lib/qt5/./libQt5Core.so.4.0
#16 0x000008bd4d1877ea in QCoreApplication::sendPostedEvents(QObject*, int) () from /usr/local/lib/qt5/./libQt5Core.so.4.0
#17 0x000008bd4d25abb8 in postEventSourceDispatch(_GSource*, int (*)(void*), void*) () from /usr/local/lib/qt5/./libQt5Core.so.4.0
#18 0x000008bde1a23c1f in g_main_context_dispatch () from /usr/local/lib/libglib-2.0.so.4201.9
#19 0x000008bde1a23fea in g_main_context_iterate () from /usr/local/lib/libglib-2.0.so.4201.9
#20 0x000008bde1a240c7 in g_main_context_iteration () from /usr/local/lib/libglib-2.0.so.4201.9
#21 0x000008bd4d25a190 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) ()
   from /usr/local/lib/qt5/./libQt5Core.so.4.0
#22 0x000008bd4d181f09 in QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) ()
   from /usr/local/lib/qt5/./libQt5Core.so.4.0
#23 0x000008bd4d182152 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/local/lib/qt5/./libQt5Core.so.4.0
#24 0x000008bd4ce5f094 in QThread::exec() () from /usr/local/lib/qt5/./libQt5Core.so.4.0
#25 0x000008bdda2bcebd in QQuickPixmapReader::run() () from /usr/local/lib/qt5/./libQt5Quick.so.4.0
#26 0x000008bd4ce6328c in QThreadPrivate::start(void*) () from /usr/local/lib/qt5/./libQt5Core.so.4.0
#27 0x000008bdb98d0ee1 in _rthread_start (v=<optimized out>) at /usr/src/lib/librthread/rthread.c:96
#28 0x000008bd00f2f27a in __tfork_thread () at /usr/src/lib/libc/arch/amd64/sys/tfork_thread.S:84

Note the value of `%rcx` suggests memory corruption:

(gdb) disassemble 
Dump of assembler code for function _ZN10QArrayData4dataEv:
   0x000008bd4ce30030 <+0>:	mov    0x4ff741(%rip),%r11        # 0x8bd4d32f778 <__retguard_2562>
   0x000008bd4ce30037 <+7>:	xor    (%rsp),%r11
   0x000008bd4ce3003b <+11>:	push   %rbp
   0x000008bd4ce3003c <+12>:	mov    %rsp,%rbp
   0x000008bd4ce3003f <+15>:	mov    %rdi,-0x8(%rbp)
   0x000008bd4ce30043 <+19>:	mov    -0x8(%rbp),%rcx
   0x000008bd4ce30047 <+23>:	mov    %rcx,%rax
=> 0x000008bd4ce3004a <+26>:	add    0x10(%rcx),%rax
   0x000008bd4ce3004e <+30>:	pop    %rbp
   0x000008bd4ce3004f <+31>:	xor    (%rsp),%r11
   0x000008bd4ce30053 <+35>:	cmp    0x4ff71e(%rip),%r11        # 0x8bd4d32f778 <__retguard_2562>
   0x000008bd4ce3005a <+42>:	je     0x8bd4ce3006f <_ZN10QArrayData4dataEv+63>
   0x000008bd4ce30060 <+48>:	int3   
...
   0x000008bd4ce3006f <+63>:	retq   
End of assembler dump.
(gdb) info registers

rax            0xdfdfdfdfdfdfdfdf  -2314885530818453537
rbx            0x8bcfab7d200       9607753224704
rcx            0xdfdfdfdfdfdfdfdf  -2314885530818453537
rdx            0x8bd81020240       9610006233664
rsi            0x0                 0
rdi            0xdfdfdfdfdfdfdfdf  -2314885530818453537
rbp            0x8bd09d09eb0       0x8bd09d09eb0
rsp            0x8bd09d09eb0       0x8bd09d09eb0
r8             0x8bd81020240       9610006233664
r9             0x8bd56ddb000       9609299210240
r10            0x8bdb889eea0       9610937888416
r11            0x1cf04888ceec81bf  2085246379896897983
r12            0x7b546758          2069129048
r13            0x1d                29
r14            0x8bda4e9ae80       9610608619136
r15            0x8bd7416c620       9609789490720
rip            0x8bd4ce3004a       0x8bd4ce3004a <QArrayData::data()+26>
eflags         0x10202             [ IF RF ]
cs             0x2b                43
ss             0x23                35
ds             0x23                35
es             0x23                35
fs             0x23                35
gs             0x23                35
fs_base        <unavailable>
gs_base        <unavailable>

To quote malloc(3) man page "freed chunks are filled with 0xdf."
https://man.openbsd.org/malloc

EXPECTED RESULT

Reliably working UI.

SOFTWARE/OS VERSIONS
OpenBSD: 7.2-current
KDE Plasma Version: n/a
KDE Frameworks Version: 5.101.0
Qt Version: 5.15.7

ADDITIONAL INFORMATION
Comment 1 kdenlive-bug 2023-01-03 05:56:55 UTC
I believe this patch is sufficient to fix the problem. It both makes `key` not be used after it was destructed and fixes the user issue:

Resolve use-after-free in thumbnailcache

Index: src/utils/thumbnailcache.cpp
--- src/utils/thumbnailcache.cpp.orig
+++ src/utils/thumbnailcache.cpp
@@ -33,8 +33,8 @@ class ThumbnailCache::Cache_t (public)
         }
         auto it = m_cache.at(key);
         m_currentCost -= (*it).second.second;
-        m_data.erase(it);
         m_cache.erase(key);
+        m_data.erase(it);
     }
 
     void insert(const QString &key, const QImage &img, int cost)
Comment 2 Bug Janitor Service 2023-01-05 03:53:15 UTC
A possibly relevant merge request was started @ https://invent.kde.org/multimedia/kdenlive/-/merge_requests/375
Comment 3 Julius Künzel 2023-02-12 20:56:30 UTC
Git commit d42e318347ad4ec71e1df7fdcc3b3459e10f90bc by Julius Künzel, on behalf of Eric Jiang.
Committed on 12/02/2023 at 20:23.
Pushed by jlskuz into branch 'master'.

Fix use-after-free in ThumbnailCache::remove()

Patch contributed by user in BUG 463764

M  +9    -2    src/utils/thumbnailcache.cpp

https://invent.kde.org/multimedia/kdenlive/commit/d42e318347ad4ec71e1df7fdcc3b3459e10f90bc