Qt application crashes with SIGBUS if XDG_CACHE_HOME is too small We were able to track down the problem to: - Package: kde-frameworks/kcoreaddons-5.51.0 - File: src/lib/caching/kshareddatacache.cpp - Function: void mapSharedMemory() - Lines: 1051 - 1053 - Code: if (file.open(QIODevice::ReadWrite) && (file.size() >= size || (file.resize(size) && ensureFileAllocated(file.handle(), size)))) { STEPS TO REPRODUCE 1) Create a small filesystem (as root): mount -t tmpfs -o size=30k tmpfs /mnt The size seems to depend on the system. If the value in '-o size=' is too small or too high, you won't get a SIGBUS crash. 30k works on my machine. 2) Create a small test program (as suggested by user "mv") File a.cc: #include <QApplication> #include <qframe.h> int main(int argc, char ** argv) { QApplication a(argc,argv); QFrame *view = new QFrame(); view->show(); a.connect(&a,SIGNAL(lastWindowClosed()),&a,SLOT(quit())); return a.exec(); } File: a.pro TARGET = a SOURCES = a.cc QT += widgets 3) Compile the program and run it: qmake && make XDG_CACHE_HOME=/mnt ./a 4) The program will crash with SIGBUS 5) You can get more details using strace: XDG_CACHE_HOME=/mnt strace -o /tmp/strace-log -f ./a 6) strace-log shows: 1500 openat(AT_FDCWD, "/mnt/icon-cache.kcache", O_RDWR|O_CREAT|O_CLOEXEC, 0666) = 9 1500 statx(9, "", AT_STATX_SYNC_AS_STAT|AT_EMPTY_PATH, STATX_ALL, {stx_mask=STATX_BASIC_STATS, stx_attributes=0, stx_mode=S_IFREG|0640, stx_size=0, ...}) = 0 1500 lseek(9, 0, SEEK_CUR) = 0 1500 ftruncate(9, 10547304) = 0 1500 fallocate(9, 0, 0, 10547304) = -1 ENOSPC (No space left on device) 1500 mmap(NULL, 10547304, PROT_READ|PROT_WRITE, MAP_SHARED, 9, 0) = 0x7f71484df000 1500 --- SIGBUS {si_signo=SIGBUS, si_code=BUS_ADRERR, si_addr=0x7f71484e3020} --- The mmap should have stopped with an error message after fallocate, since this function failed. But the error was ignored and the program continued with an mmap. A subsequent memory access to the mmaped memory failed with SIGBUS. 7) The lines in the strace log correspond to lines 1051 - 1053 of src/lib/caching/kshareddatacache.cpp OBSERVED RESULT: SIGBUS EXPECTED RESULT: Error message stating that XDG_CACHE_HOME is out of space, followed by a regular abort() or exit(). SOFTWARE VERSIONS - OS: Gentoo Linux - KDE Plasma Version: 5.14.2 - KDE Frameworks Version: 5.51.0 - Qt Version: 5.11.2 ADDITIONAL INFORMATION - Look at https://forums.gentoo.org/viewtopic-t-1087812.html for additional information.
I can reproduce this in Neon dev-unstable 18.04 (crashes every second run, or prints "Unable to acquire shared lock, is the cache corrupt?").
Proposed fix: https://phabricator.kde.org/D16744
Git commit eb916c305a5cd8683e7e8f955740a7c810220e19 by Alexey Min. Committed on 07/11/2018 at 23:33. Pushed by alexeymin into branch 'master'. Fix crash if XDG_CACHE_HOME directory is too small or out of space Summary: Incorrect checking for error return code of posix_fallocate() causes function to think that everything is OK, while it is not, causing crash in some cases. Related: bug 339829 Test Plan: good test plan provided in https://bugs.kde.org/show_bug.cgi?id=400610 . Works like a charm, tested in KDE Neon dev-ustable The reason for bug was that return value of posix_fallocate() was assumed to be negative on error, but in fact it is a positive integer. The check was `< 0`, whi should be `!= 0`. ( http://man7.org/linux/man-pages/man3/posix_fallocate.3.html ) With this fix applied test application does not crash, and the output in console widow is: ``` No space left on device. Check filesystem free space at your XDG_CACHE_HOME! The operating system is unable to promise 10547304 bytes for mapped cache, abandoning the cache for crash-safety. org.kde.kcoreaddons: Failed to establish shared memory mapping, will fallback to private memory -- memory usage will increase ``` Reviewers: dfaure, #frameworks, mpyne Reviewed By: dfaure Subscribers: cfeck, kde-frameworks-devel Tags: #frameworks Differential Revision: https://phabricator.kde.org/D16744 M +4 -1 src/lib/caching/kshareddatacache_p.h https://commits.kde.org/kcoreaddons/eb916c305a5cd8683e7e8f955740a7c810220e19
@Alexey Min: thanks for fixing this bug so quickly! :-)
For the sake of completeness: I found a very similar problem in Qt (same test program, missing test before mmap()): https://bugreports.qt.io/browse/QTQAINFRA-2381