Bug 346214

Summary: invalid proxy causes hang
Product: [Frameworks and Libraries] frameworks-kio Reporter: Jonathan Riddell <jr>
Component: generalAssignee: David Faure <faure>
Status: RESOLVED FIXED    
Severity: normal CC: kde, kdelibs-bugs
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed In: 5.11
Sentry Crash Report:

Description Jonathan Riddell 2015-04-15 10:54:14 UTC
if I set an invalid proxy and try to use kio then it'll freeze the application which isn't very user friendly

backtrace from gdb:
#0  syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
#1  0x00007ffff64f0940 in QBasicMutex::lockInternal() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#2  0x00007ffff7382cc4 in KProtocolManager::proxiesForUrl(QUrl const&) () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#3  0x00007ffff738466d in KProtocolManager::slaveProtocol(QUrl const&, QStringList&) () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#4  0x00007ffff7375010 in ?? () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#5  0x00007ffff7361ba1 in ?? () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#6  0x00007ffff7364c19 in KIO::StatJob::StatJob(KIO::StatJobPrivate&) () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#7  0x00007ffff73654d3 in KIO::stat(QUrl const&, KIO::StatJob::StatSide, short, QFlags<KIO::JobFlag>) () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#8  0x00007ffff731c734 in ?? () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#9  0x00007ffff731de87 in ?? () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#10 0x00007ffff67679c9 in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#11 0x00007ffff7b8b2b2 in KJob::result(KJob*, KJob::QPrivateSignal) () from /usr/lib/x86_64-linux-gnu/libKF5CoreAddons.so.5
#12 0x00007ffff7b8bdba in KJob::emitResult() () from /usr/lib/x86_64-linux-gnu/libKF5CoreAddons.so.5
#13 0x00007ffff7361ebb in KIO::SimpleJob::slotFinished() () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#14 0x00007ffff7365e0e in KIO::StatJob::slotFinished() () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#15 0x00007ffff7365761 in ?? () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#16 0x00007ffff67679c9 in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#17 0x00007ffff7345641 in KIO::SlaveInterface::dispatch(int, QByteArray const&) () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#18 0x00007ffff7342bd7 in KIO::SlaveInterface::dispatch() () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#19 0x00007ffff7347316 in KIO::Slave::gotInput() () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#20 0x00007ffff73c5a45 in ?? () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#21 0x00007ffff67679c9 in QMetaObject::activate(QObject*, int, int, void**) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#22 0x00007ffff72f0870 in ?? () from /usr/lib/x86_64-linux-gnu/libKF5KIOCore.so.5
#23 0x00007ffff676873a in QObject::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#24 0x00007ffff6af3b2c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#25 0x00007ffff6af9000 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5
#26 0x00007ffff6736c2b in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#27 0x00007ffff6738c9b in QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#28 0x00007ffff678f843 in ?? () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#29 0x00007ffff2f2fc3d in g_main_context_dispatch () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#30 0x00007ffff2f2ff20 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#31 0x00007ffff2f2ffcc in g_main_context_iteration () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#32 0x00007ffff678fc57 in QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#33 0x00007ffff67343e2 in QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#34 0x00007ffff673c02c in QCoreApplication::exec() () from /usr/lib/x86_64-linux-gnu/libQt5Core.so.5
#35 0x0000000000405cb8 in ClientApp::doCopy(QStringList const&) ()
#36 0x0000000000406a3f in ClientApp::doIt(QCommandLineParser const&) ()
#37 0x0000000000404452 in main ()


Reproducible: Always

Steps to Reproduce:
1.in systemsettings -> network settings -> proxy set use manually specified proxy config and set SOCKS proxy to "localhost" 8080
2. do not start a proxy
3. run>  kioclient5 copy http://google.com .

Actual Results:  
freezes

Expected Results:  
it should give a sane error (e.g. firefox pops up a warning about proxy not responding)
Comment 1 Justin Paupore 2015-04-24 09:53:41 UTC
Can confirm this issue. It actually triggers on *any* proxy configuration, even valid ones. (Tested with a local mitmproxy instance.)

Here's a backtrace with debuginfo:

#0  syscall () at ../sysdeps/unix/sysv/linux/x86_64/syscall.S:38
#1  0x00007ffff64f0940 in _q_futex (op=<optimized out>, val=<optimized out>, timeout=<optimized out>, addr=<optimized out>) at thread/qmutex_linux.cpp:146
#2  lockInternal_helper<false> (timeout=<optimized out>, elapsedTimer=<optimized out>, d_ptr=...) at thread/qmutex_linux.cpp:187
#3  QBasicMutex::lockInternal (this=this@entry=0x7ffff7607e40 <(anonymous namespace)::Q_QGS_kProtocolManagerPrivate::innerFunction()::holder>) at thread/qmutex_linux.cpp:203
#4  0x00007ffff64f09e9 in QMutex::lock (this=this@entry=0x7ffff7607e40 <(anonymous namespace)::Q_QGS_kProtocolManagerPrivate::innerFunction()::holder>) at thread/qmutex.cpp:217
#5  0x00007ffff7382cc4 in QMutexLocker (m=0x7ffff7607e40 <(anonymous namespace)::Q_QGS_kProtocolManagerPrivate::innerFunction()::holder>, this=<synthetic pointer>) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qmutex.h:128
#6  KProtocolManager::proxiesForUrl (url=...) at ../../../src/core/kprotocolmanager.cpp:535
#7  0x00007ffff738466d in KProtocolManager::slaveProtocol (url=..., proxyList=...) at ../../../src/core/kprotocolmanager.cpp:654
#8  0x00007ffff7375010 in KIO::SchedulerPrivate::doJob (this=0x887900, job=job@entry=0x8872e0) at ../../../src/core/scheduler.cpp:954
#9  0x00007ffff73753f5 in KIO::Scheduler::doJob (job=job@entry=0x8872e0) at ../../../src/core/scheduler.cpp:792
#10 0x00007ffff7361ba1 in KIO::SimpleJobPrivate::simpleJobInit (this=<optimized out>) at ../../../src/core/simplejob.cpp:48
#11 0x00007ffff736bab9 in KIO::TransferJob::TransferJob (this=0x8872e0, dd=...) at ../../../src/core/transferjob.cpp:32
#12 0x00007ffff736c2bc in newJob (flags=..., _staticData=..., packedArgs=..., command=67, url=...) at ../../../src/core/job_p.h:293
#13 KIO::get (url=..., reload=KIO::NoReload, flags=...) at ../../../src/core/transferjob.cpp:432
#14 0x0000000000406063 in ClientApp::doIt(QCommandLineParser const&) ()
#15 0x0000000000404452 in main ()

The root cause of this seems to be in KProtocolManager - KProtocolManager::slaveProtocol locks kProtocolManagerPrivate()->mutex (kprotocolmanager.cpp:646), then calls KProtocolManager::proxiesForUrl (line 654), which tries to lock the same non-recursive mutex (line 535), causing an instant deadlock. If proxies are turned off, slaveProtocol bails early (lines 638-39), which explains how this made it through testing.
Comment 2 David Faure 2015-05-15 00:26:47 UTC
Git commit 9b600da2a5cb8b1881dd670144bf7218b17ccf2b by David Faure.
Committed on 15/05/2015 at 00:26.
Pushed by dfaure into branch 'master'.

Fix single-thread deadlocks when using proxies
FIXED-IN: 5.11
CHANGELOG: fix deadlock when using network proxies

Change-Id: I216d365f21fb2be886e8515cf255cf49c1bad115

M  +30   -0    autotests/kprotocolinfotest.cpp
M  +53   -27   src/core/kprotocolmanager.cpp

http://commits.kde.org/kio/9b600da2a5cb8b1881dd670144bf7218b17ccf2b