Changeset 6146

Show
Ignore:
Timestamp:
2008-04-13 11:11:50 (1 month ago)
Author:
emostar
Message:

Prevent a DoS that crashed licq by using too many descriptors.
Fixes #1623

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/licq/include/licq_socket.h

    r4714 r6146  
    251251  fd_set SocketSet()   {  return m_sSockets.SocketSet(); } 
    252252  int LargestSocket()  {  return m_sSockets.Largest(); } 
     253  unsigned short Num() {  return m_sSockets.Num(); } 
    253254 
    254255protected: 
  • trunk/licq/src/icqd-chat.cpp

    r6136 r6146  
    2424#include "gettext.h" 
    2525 
     26#define MAX_CONNECTS  256 
    2627#define DEBUG_THREADS(x) 
    2728 
     
    23842385        else if (nCurrentSocket == chatman->chatServer.Descriptor()) 
    23852386        { 
    2386           CChatUser *u = new CChatUser; 
    2387           u->m_pClient = new CChatClient; 
    2388  
    2389           chatman->chatServer.RecvConnection(u->sock); 
    2390           chatman->sockman.AddSocket(&u->sock); 
    2391           chatman->sockman.DropSocket(&u->sock); 
    2392  
    2393           u->state = CHAT_STATE_HANDSHAKE; 
    2394           chatman->chatUsers.push_back(u); 
    2395           gLog.Info(tr("%sChat: Received connection.\n"), L_TCPxSTR); 
     2387          if (chatman->sockman.Num() >= MAX_CONNECTS) 
     2388          { 
     2389            // Too many sockets, drop this one 
     2390            gLog.Warn(tr("%sToo many connected clients, rejecting new connection.\n"), L_WARNxSTR); 
     2391          } 
     2392          else 
     2393          { 
     2394            CChatUser *u = new CChatUser; 
     2395            u->m_pClient = new CChatClient; 
     2396 
     2397            chatman->chatServer.RecvConnection(u->sock); 
     2398            chatman->sockman.AddSocket(&u->sock); 
     2399            chatman->sockman.DropSocket(&u->sock); 
     2400 
     2401            u->state = CHAT_STATE_HANDSHAKE; 
     2402            chatman->chatUsers.push_back(u); 
     2403            gLog.Info(tr("%sChat: Received connection.\n"), L_TCPxSTR); 
     2404          } 
    23962405        } 
    23972406 
  • trunk/licq/src/icqd-threads.cpp

    r5450 r6146  
    2424#include "gettext.h" 
    2525 
     26#define MAX_CONNECTS  256 
    2627#define DEBUG_THREADS(x) 
    2728//#define DEBUG_THREADS(x) gLog.Info(x) 
     
    781782              tcp->RecvConnection(*newSocket); 
    782783              gSocketManager.DropSocket(tcp); 
    783               gSocketManager.AddSocket(newSocket); 
    784               gSocketManager.DropSocket(newSocket); 
     784 
     785              // Make sure we can handle another socket before accepting it 
     786              if (gSocketManager.Num() > MAX_CONNECTS) 
     787              { 
     788                // Too many sockets, drop this one 
     789                char remoteIp[32]; 
     790                gLog.Warn(tr("%sToo many connected sockets, rejecting connection from %s.\n"), 
     791                    L_WARNxSTR, newSocket->RemoteIpStr(remoteIp)); 
     792                delete newSocket; 
     793              } 
     794              else 
     795              { 
     796                gSocketManager.AddSocket(newSocket); 
     797                gSocketManager.DropSocket(newSocket); 
     798              } 
    785799            } 
    786800          } 
  • trunk/licq/src/socket.cpp

    r5629 r6146  
    818818  socklen_t sizeofSockaddr = sizeof(struct sockaddr_in); 
    819819 
    820   newSocket.m_nDescriptor = accept(m_nDescriptor, (struct sockaddr *)&newSocket.m_sRemoteAddr, &sizeofSockaddr); 
    821   newSocket.SetLocalAddress(); 
     820  // Make sure we stay under FD_SETSIZE 
     821  // See: 
     822  // * http://www.securityfocus.com/archive/1/490711 
     823  // * http://securityvulns.com/docs7669.html 
     824  // for more details 
     825  // This probably has no affect, since we are using multiple threads, but keep it here  
     826  // to be used as a sanity check. 
     827  int newDesc = accept(m_nDescriptor, (struct sockaddr *)&newSocket.m_sRemoteAddr, &sizeofSockaddr); 
     828  if (newDesc < FD_SETSIZE) 
     829  { 
     830    newSocket.m_nDescriptor = newDesc; 
     831    newSocket.SetLocalAddress(); 
     832  } 
     833  else 
     834  { 
     835    gLog.Error(tr("%sCannot accept new connection, too many descriptors in use.\n"), L_ERRORxSTR); 
     836    close(newDesc); 
     837 
     838    // TODO throw an exception, or do something to tell the caller it failed 
     839  } 
    822840} 
    823841