Handle invalid handshake data properly in the core
authorManuel Nickschas <sputnick@quassel-irc.org>
Sun, 24 Apr 2016 19:59:15 +0000 (21:59 +0200)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sun, 24 Apr 2016 19:59:15 +0000 (21:59 +0200)
Clients sending invalid handshake data could make the core crash
due to an unchecked pointer. This commit fixes this issue by having
the core close the socket if a peer could not be created.

Thanks to Bas Pape (Tucos) for finding this one!

src/common/peerfactory.cpp
src/core/coreauthhandler.cpp

index 580c2ba..cd0987b 100644 (file)
@@ -56,5 +56,5 @@ RemotePeer *PeerFactory::createPeer(const ProtoList &protocols, AuthHandler *aut
         }
     }
 
         }
     }
 
-    return 0;
+    return nullptr;
 }
 }
index e380924..34fc222 100644 (file)
@@ -81,7 +81,7 @@ void CoreAuthHandler::onReadyRead()
     }
 
     // read the list of protocols supported by the client
     }
 
     // read the list of protocols supported by the client
-    while (socket()->bytesAvailable() >= 4) {
+    while (socket()->bytesAvailable() >= 4 && _supportedProtos.size() < 16) { // sanity check
         quint32 data;
         socket()->read((char*)&data, 4);
         data = qFromBigEndian<quint32>(data);
         quint32 data;
         socket()->read((char*)&data, 4);
         data = qFromBigEndian<quint32>(data);
@@ -98,6 +98,12 @@ void CoreAuthHandler::onReadyRead()
                 level = Compressor::NoCompression;
 
             RemotePeer *peer = PeerFactory::createPeer(_supportedProtos, this, socket(), level, this);
                 level = Compressor::NoCompression;
 
             RemotePeer *peer = PeerFactory::createPeer(_supportedProtos, this, socket(), level, this);
+            if (!peer) {
+                qWarning() << "Received invalid handshake data from client" << socket()->peerAddress().toString();
+                close();
+                return;
+            }
+
             if (peer->protocol() == Protocol::LegacyProtocol) {
                 _legacy = true;
                 connect(peer, SIGNAL(protocolVersionMismatch(int,int)), SLOT(onProtocolVersionMismatch(int,int)));
             if (peer->protocol() == Protocol::LegacyProtocol) {
                 _legacy = true;
                 connect(peer, SIGNAL(protocolVersionMismatch(int,int)), SLOT(onProtocolVersionMismatch(int,int)));