Bug 246576 - Crash on invalid input data from server
Summary: Crash on invalid input data from server
Status: RESOLVED FIXED
Alias: None
Product: konversation
Classification: Applications
Component: general (show other bugs)
Version: 1.3.1
Platform: Fedora RPMs Linux
: NOR crash
Target Milestone: ---
Assignee: Konversation Developers
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-08-03 07:14 UTC by Jonas Thiem
Modified: 2010-08-03 11:30 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
that little tool I used (19.73 KB, application/x-gzip)
2010-08-03 07:22 UTC, Jonas Thiem
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Jonas Thiem 2010-08-03 07:14:13 UTC
Application: konversation (1.3.1)
KDE Platform Version: 4.4.5 (KDE 4.4.5)
Qt Version: 4.6.3
Operating System: Linux 2.6.33.6-147.fc13.i686.PAE i686
Distribution: "Fedora release 13 (Goddard)"

-- Information about the crash:
This crash has been instantly triggered by Konversation when connecting it to Yarcs Crazy Exploding IRC Fuzzer ;-)

I can reproduce it constantly. I hope this helps.

The crash can be reproduced every time.

 -- Backtrace:
Application: Konversation (konversation), signal: Segmentation fault
[KCrash Handler]
#6  _int_free (av=0x2d8f3a0, p=0x896abb8, have_lock=0) at malloc.c:4873
#7  0x0113884e in qFree (ptr=0x896abc0) at global/qmalloc.cpp:60
#8  0x011852b1 in QString::free (d=0x896abc0) at tools/qstring.cpp:1108
#9  0x080e7c3d in ~QString (this=0x8c32920) at /usr/include/QtCore/qstring.h:869
#10 Server::incoming (this=0x8c32920) at /usr/src/debug/konversation-1.3.1/src/irc/server.cpp:1060
#11 0x080ea76f in Server::qt_metacall (this=0x8c32920, _c=QMetaObject::InvokeMetaMethod, _id=87, _a=0xbfdc378c) at /usr/src/debug/konversation-1.3.1/i686-redhat-linux-gnu/src/server.moc:413
#12 0x012338ab in QMetaObject::metacall (object=0x8c32920, cl=QMetaObject::InvokeMetaMethod, idx=91, argv=0xbfdc378c) at kernel/qmetaobject.cpp:237
#13 0x01242755 in QMetaObject::activate (sender=0x88f1d10, m=0x7920484, local_signal_index=2, argv=0x0) at kernel/qobject.cpp:3295
#14 0x0781b578 in KTcpSocket::readyRead (this=0x88f1d10) at /usr/src/debug/kdelibs-4.4.5/i686-redhat-linux-gnu/kdecore/ktcpsocket.moc:148
#15 0x0781e9f6 in reemitReadyRead (this=0x88f1d10, _c=QMetaObject::InvokeMetaMethod, _id=14, _a=0xbfdc38dc) at /usr/src/debug/kdelibs-4.4.5/kdecore/network/ktcpsocket.cpp:353
#16 KTcpSocket::qt_metacall (this=0x88f1d10, _c=QMetaObject::InvokeMetaMethod, _id=14, _a=0xbfdc38dc) at /usr/src/debug/kdelibs-4.4.5/i686-redhat-linux-gnu/kdecore/ktcpsocket.moc:120
#17 0x012338ab in QMetaObject::metacall (object=0x88f1d10, cl=QMetaObject::InvokeMetaMethod, idx=22, argv=0xbfdc38dc) at kernel/qmetaobject.cpp:237
#18 0x01242755 in QMetaObject::activate (sender=0x8af8cb8, m=0x1343dc8, local_signal_index=0, argv=0x0) at kernel/qobject.cpp:3295
#19 0x01289198 in QIODevice::readyRead (this=0x8af8cb8) at .moc/release-shared/moc_qiodevice.cpp:91
#20 0x04df1678 in QSslSocketPrivate::_q_readyReadSlot (this=0x929bb18) at ssl/qsslsocket.cpp:2131
#21 0x04df4386 in QSslSocket::qt_metacall (this=0x8af8cb8, _c=QMetaObject::InvokeMetaMethod, _id=<value optimized out>, _a=0xbfdc3a2c) at .moc/release-shared/moc_qsslsocket.cpp:121
#22 0x012338ab in QMetaObject::metacall (object=0x8af8cb8, cl=QMetaObject::InvokeMetaMethod, idx=39, argv=0xbfdc3a2c) at kernel/qmetaobject.cpp:237
#23 0x01242755 in QMetaObject::activate (sender=0x87f8b18, m=0x1343dc8, local_signal_index=0, argv=0x0) at kernel/qobject.cpp:3295
#24 0x01289198 in QIODevice::readyRead (this=0x87f8b18) at .moc/release-shared/moc_qiodevice.cpp:91
#25 0x04dd9ef2 in QAbstractSocketPrivate::canReadNotification (this=0x98985a0) at socket/qabstractsocket.cpp:639
#26 0x04dc84cc in QAbstractSocketEngine::readNotification (this=0x87ea3b8) at socket/qabstractsocketengine.cpp:154
#27 0x04dc9523 in QReadNotifier::event (this=0x8c8cde0, e=0xbfdc3ee4) at socket/qnativesocketengine.cpp:1097
#28 0x01468bdc in QApplicationPrivate::notify_helper (this=0x85ab680, receiver=0x8c8cde0, e=0xbfdc3ee4) at kernel/qapplication.cpp:4306
#29 0x0146f636 in QApplication::notify (this=0xbfdc4224, receiver=0x8c8cde0, e=0xbfdc3ee4) at kernel/qapplication.cpp:3710
#30 0x05c2600b in KApplication::notify (this=0xbfdc4224, receiver=0x8c8cde0, event=0xbfdc3ee4) at /usr/src/debug/kdelibs-4.4.5/kdeui/kernel/kapplication.cpp:302
#31 0x0122ee13 in QCoreApplication::notifyInternal (this=0xbfdc4224, receiver=0x8c8cde0, event=0xbfdc3ee4) at kernel/qcoreapplication.cpp:726
#32 0x012574fa in sendEvent (source=0x85afc10) at kernel/qcoreapplication.h:215
#33 socketNotifierSourceDispatch (source=0x85afc10) at kernel/qeventdispatcher_glib.cpp:110
#34 0x05ed9525 in g_main_dispatch (context=0x85af090) at gmain.c:1960
#35 IA__g_main_context_dispatch (context=0x85af090) at gmain.c:2513
#36 0x05edd268 in g_main_context_iterate (context=0x866490, block=1, dispatch=1, self=0x85a2dd0) at gmain.c:2591
#37 0x05edd449 in IA__g_main_context_iteration (context=0x85af090, may_block=1) at gmain.c:2654
#38 0x01257126 in QEventDispatcherGlib::processEvents (this=0x8582c18, flags=...) at kernel/qeventdispatcher_glib.cpp:412
#39 0x01517796 in QGuiEventDispatcherGlib::processEvents (this=0x8582c18, flags=...) at kernel/qguieventdispatcher_glib.cpp:204
#40 0x0122d4ea in QEventLoop::processEvents (this=0xbfdc4184, flags=...) at kernel/qeventloop.cpp:149
#41 0x0122d82a in QEventLoop::exec (this=0xbfdc4184, flags=...) at kernel/qeventloop.cpp:201
#42 0x012314e7 in QCoreApplication::exec () at kernel/qcoreapplication.cpp:1003
#43 0x01468c88 in QApplication::exec () at kernel/qapplication.cpp:3585
#44 0x080a5783 in main (argc=1, argv=0x0) at /usr/src/debug/konversation-1.3.1/src/main.cpp:101

Possible duplicates by query: bug 242656.

Reported using DrKonqi
Comment 1 Jonas Thiem 2010-08-03 07:22:34 UTC
Created attachment 49763 [details]
that little tool I used
Comment 2 Eike Hein 2010-08-03 11:30:28 UTC
commit a2acea6319ec0308527ee656b1df200f1fe00f28
Author: Eike Hein <hein@kde.org>
Date:   Tue Aug 3 11:29:37 2010 +0200

    Don't crash on Jonas Thiem's fuzzer.
    
    Fixed a small loop logic error in incoming(), a missing length
    sanity check after the encoding pass and a source of QList::last()
    calls on an empty list.
    
    BUG:246576

diff --git a/ChangeLog b/ChangeLog
index 396004b..3c10d30 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -115,6 +115,7 @@ Changes since 1.3.1:
     tection of email addresses.
   - Average performance of link detection has improved slightly.
 * Incoming actions (i.e. "/me") without an argument are now handled properly.
+* Fixed a number of crashes on illegal data from the server.
 
 
 Changes from 1.3 to 1.3.1:
diff --git a/src/commit.h b/src/commit.h
index 2946f3b..8a5cc24 100644
--- a/src/commit.h
+++ b/src/commit.h
@@ -1,4 +1,4 @@
 // This COMMIT number is added to version string to be used as "patch level"
 #ifndef COMMIT
-#define COMMIT 4068
+#define COMMIT 4069
 #endif
diff --git a/src/irc/inputfilter.cpp b/src/irc/inputfilter.cpp
index ba1828a..7948c63 100644
--- a/src/irc/inputfilter.cpp
+++ b/src/irc/inputfilter.cpp
@@ -153,7 +153,7 @@ void InputFilter::parseLine(const QString& line)
     }
 }
 
-#define trailing parameterList.last()
+#define trailing (parameterList.isEmpty() ? QString() : parameterList.last())
 #define plHas(x) _plHas(parameterList.count(), (x))
 
 bool _plHad=false;
diff --git a/src/irc/server.cpp b/src/irc/server.cpp
index 8166332..72a3bba 100644
--- a/src/irc/server.cpp
+++ b/src/irc/server.cpp
@@ -1100,13 +1100,15 @@ void Server::incoming()
         QTextCodec* codec = getIdentity()->getCodec();
         QByteArray first = bufferLines.first();
 
+        bufferLines.removeFirst();
+
         QStringList lineSplit = codec->toUnicode(first).split(' ', QString::SkipEmptyParts);
 
-        if( lineSplit.count() >= 1 )
+        if (lineSplit.count() >= 1)
         {
-            if( lineSplit[0][0] == ':' )          // does this message have a prefix?
+            if (lineSplit[0][0] == ':')          // does this message have a prefix?
             {
-                if( !lineSplit[0].contains('!') ) // is this a server(global) message?
+                if(!lineSplit[0].contains('!')) // is this a server(global) message?
                     isServerMessage = true;
                 else
                     senderNick = lineSplit[0].mid(1, lineSplit[0].indexOf('!')-1);
@@ -1114,13 +1116,9 @@ void Server::incoming()
                 lineSplit.removeFirst();          // remove prefix
             }
         }
-        else
-        {
-            // The line contained only spaces (other than CRLF, removed above)
-            // and thus there's nothing more we can do with it.
-            bufferLines.removeFirst();
+
+        if (lineSplit.isEmpty())
             continue;
-        }
 
         // BEGIN pre-parse to know where the message belongs to
         QString command = lineSplit[0].toLower();
@@ -1200,8 +1198,10 @@ void Server::incoming()
         #endif
         bool isUtf8 = Konversation::isUtf8(first);
 
+        QString encoded;
+
         if (isUtf8)
-            m_inputBuffer << QString::fromUtf8(first);
+            encoded = QString::fromUtf8(first);
         else
         {
             // check setting
@@ -1223,15 +1223,16 @@ void Server::incoming()
             if (codec->mibEnum() == 106)
                 codec = QTextCodec::codecForMib( 4 /* iso-8859-1 */ );
 
-            m_inputBuffer << codec->toUnicode(first);
+            encoded = codec->toUnicode(first);
         }
 
-        bufferLines.removeFirst();
-
         // Qt uses 0xFDD0 and 0xFDD1 to mark the beginning and end of text frames. Remove
         // these here to avoid fatal errors encountered in QText* and the event loop pro-
         // cessing.
-        sterilizeUnicode(m_inputBuffer.back());
+        sterilizeUnicode(encoded);
+
+        if (!encoded.isEmpty())
+            m_inputBuffer << encoded;
 
         //FIXME: This has nothing to do with bytes, and it's not raw received bytes either. Bogus number.
         //m_bytesReceived+=m_inputBuffer.back().length();