Subject: BUG - 1.3.n accept fails if NULL sockaddr * argument and other related stuff.
From: "Mike Thomas" <[email-masked]>
To: <[email-masked]>
Cc: "Andreas. Lange" <[email-masked]>, "Glynn Clements" <[email-masked]>
Date: Wed, 1 Aug 2001 13:25:29 +1000

Hi there.

The following function (open source GIS package GRASS) dies when accept
is called.  Replacing the NULL argument with a valid pointer stopped the
crash.  I am told that "accept()" should be able to deal with a NULL
argument - certainly this code works on several Unices.

----------------------------------------------------------------------------
----------------------
/* -----------------------------------------------------------------------
 * G_sock_accept (int sockfd):
 * Wrapper around the accept() function. No client info is returned, but
 * that's not generally useful for local sockets anyway.  Function returns
 * the file descriptor or an error code generated by accept().  Note,
 * this call will usually block until a connection arrives.  You can use
 * select() for a time out on the call.
 * ---------------------------------------------------------------------*/

int
G_sock_accept (int sockfd)
{   
    return accept (sockfd, (struct sockaddr *) NULL, NULL);
}

------------------------------------------------------------------------------------------------

Looking at the Cygwin source below, I see that if the length argument is too small
it is corrected, but no similar check is made for the argument "peer".

------------------------------------------------------------------------------------------------
cygwin_accept (int fd, struct sockaddr *peer, int *len)
{
  int res = -1;
  BOOL secret_check_failed = FALSE;
  BOOL in_progress = FALSE;
  sigframe thisframe (mainthread);

  fhandler_socket *sock = get (fd);
  if (sock)
    {
      /* accept on NT fails if len < sizeof (sockaddr_in)
       * some programs set len to
       * sizeof (name.sun_family) + strlen (name.sun_path) for UNIX domain
       */
      if (len && ((unsigned) *len < sizeof (struct sockaddr_in)))
        *len = sizeof (struct sockaddr_in);

      res = accept (sock->get_socket (), peer, len);  // can't use a blocking call inside a lock

---------------------------------------------
---------------------------------------------------

QUESTION:

Is the "accept()" call inside "cygwin_accept()" the winsock.dll "accept()"?

OTHER ISSUES:

I point these two out for attention from the Cygwin experts on socket
implementation.

1. socket.h does not include a type "socklen_t" which is apparently defined
on some Unix platforms.

2. Although not relevant to the code above, I noticed while looking in
socket.h and friends that Cygwin provides sockaddr and sockaddr_un, which
differ in terms of how much space is made for the name of the socket.  The
sockaddr member sa_data is only very short (14 bytes, compared to
UNIX_PATH_LEN for the sun_path member of sockaddr_un) which would not
suffice for a long file name.  Unfortunately accept is defined in terms of
sockaddr rather than sockaddr_un which could potentially cause string
overwrites.

Cheers

Mike Thomas.

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/