This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] bsd_tcpip: fix socket leak in accept()


The attached patch fixes a socket leak in the bsd_tcpip stack that
happens when an incoming TCP connection is reset by the client
immediately after the connection is established.  When this occurs,
the accept() call returns -1 with errno==353, and a socket structure
is leaked.

For more details, see

http://thread.gmane.org/gmane.os.ecos.general/27351/focus=27357


The attached Win32 C program can be used to trigger the leak in any
eCos program that accepts incoming TCP connections.  [I've only tested
this program using Cygwin's gcc in "mingw" cross-compile mode to
produce a native Win32 executable.]

I was unable to get a Linux client to produce a TCP RST in a manner
that would cause problems.

-- 
Grant Edwards
grant.b.edwards@gmail.com

Attachment: eCos-bsd_tcpip-socket-leak.patch
Description: application/patch

#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>


int main(int argc, char *argv[])
{
  WSADATA wsaData;
  BOOL dontlinger=0;
  int sock;
  int loops;
  struct sockaddr_in servAddr;
  char *host;
  int   port;

  if (argc != 3)
    {
      fprintf(stderr,"usage: %s host port\n",argv[0]);
      exit(1);
    }

  host = argv[1];
  port = atoi(argv[2]);

  if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) /* Load Winsock 2.0 DLL */
    {
      fprintf(stderr, "WSAStartup() failed");
      exit(1);
    }

  memset(&servAddr, 0, sizeof(servAddr));
  servAddr.sin_family      = AF_INET;
  servAddr.sin_addr.s_addr = inet_addr(host);
  servAddr.sin_port        = htons(port);

  loops = 1;

  printf("starting\n");

  while (1)
    {
      if ( (sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
        {
          perror("socket() failed:");
          exit(1);
        }

      setsockopt(sock,SOL_SOCKET,SO_DONTLINGER,(char *)&dontlinger,sizeof(BOOL));

      if (connect(sock, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0)
        {
          printf("connect() failed, sleeping...\n");
          Sleep(1000);
        }
      else
        {
          printf("%4d\n",loops);
          ++loops;
        }

      closesocket(sock);
      Sleep(250);
    }

  WSACleanup();
  return 0;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]