This is the mail archive of the cygwin mailing list for the Cygwin 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]

Re: [1.7] Updated: cygwin-1.7.0-65

On Nov 20 10:14, Huang Bambo wrote:
> I think there maybe some bug with new "socket duplication" function.
> While I use ssh to connect remote cygwin, with previous version of
> cygwin, after type exit command, shell will close and sshd will close
> the connection forwardly but with 65 version connection will not close
> by sshd untile I type "net stop sshd" to stop sshd service.

That's weird.  I can not reproduce it.  Here's what happens in -65:

Normally sockets are inheritable system objects.  They can be duplicated
via DuplicateHandle and they can be inherited to child processes in
calls to CreateProcess.
Some applications install a so-called socket provider which is added to
the Windows socket stack.  These socket providers act like a filter
driver between the applicaton and the OS sockets.  From the application
perspective they are still sockets, but depending on how the filter
driver is written, they lack certain features.  One of them is the
abilty to be duplicated via DuplicateHandle and to be inherited to child

If that's the case we need to duplicate sockets using a complicated
mechanism using one call in the parent process (WSADuplicateSocket) and
one call in the child process (WSASocket).
So what Cygwin now does is trying to figure out if the just created
socket is a "good", inheritable socket, or a "bad", non-inheritable
socket.  In the first case, the usual duplication is used, in the
second case, WSADuplicateSocket/WSASocket is used.

When testing ssh connections, I have no problems either way.  Usually
I have no 3rd party socket providers installed, so my machines use the
default way for "good" sockets.  If I enforce the usage of the code for
"bad" sockets, it still works fine and the connection is closed
immediately on exit.

Your description of the problem implies that it worked fine for you
so far, as long as Cygwin 1.7 was only using the "good" socket method.
When using -65, Cygwin tries to figure out what kind of socket your
socket is and apparently finds it to be a "bad" socket so it uses the
matching socket duplication technique.

The bad joke here is this:  Per MSDN, the "bad" socket method is the
only blessed one.  So, *if* onle of these methods is supposed to
work every time, it's that method.

That's annoying.  I hate to say that in this case, but could you
please check for potential BLODAs per this list:

And, for a start, can you please run the below testcase and paste the
output into your reply?

$ cat > dup-sock.c << EOF
#include <stdio.h>
#include <windows.h>
#include <winsock2.h>
#include <ws2spi.h>
#include <ddk/ntapi.h>
#include <ddk/ntifs.h>

main (int argc, char **argv)
  WSADATA wsadata;
  SOCKET sock_fd;
  NTSTATUS status;
  ULONG len = 0;
  int i;

  WSAStartup ((2<<8) | 2, &wsadata);
  sock_fd = socket (AF_INET, SOCK_STREAM, 0);
  if (sock_fd < 0)
      printf ("socket failed: %lu\n", WSAGetLastError ());
      return 1;

  status = ZwQueryObject ((HANDLE) sock_fd, ObjectHandleInformation,
			  &ohai, sizeof ohai, NULL);
  if (!NT_SUCCESS (status))
    printf ("NtQueryObject failed: %p\n", status);
    printf ("Inherit: %d\n", ohai.Inherit);

  if (WSADuplicateSocketA (sock_fd, GetCurrentProcessId (), &pinf))
    printf ("WSADuplicateSocket failed: %lu\n", WSAGetLastError ());
      WCHAR path[256];
      INT len = 256;
      INT err;

      printf ("dwServiceFlags1: %p\n", pinf.dwServiceFlags1);
      printf ("dwServiceFlags2: %p\n", pinf.dwServiceFlags2);
      printf ("dwServiceFlags3: %p\n", pinf.dwServiceFlags3);
      printf ("dwServiceFlags4: %p\n", pinf.dwServiceFlags4);
      printf ("dwProviderFlags: %p\n", pinf.dwProviderFlags);
      printf ("ProviderId: %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X\n",
	      pinf.ProviderId.Data1, pinf.ProviderId.Data2,
	      pinf.ProviderId.Data4[0], pinf.ProviderId.Data4[1],
	      pinf.ProviderId.Data4[2], pinf.ProviderId.Data4[3],
	      pinf.ProviderId.Data4[4], pinf.ProviderId.Data4[5],
	      pinf.ProviderId.Data4[6], pinf.ProviderId.Data4[7]);
      printf ("dwCatalogEntryId: %p\n", pinf.dwCatalogEntryId);
      printf ("ProtocolChain: [len: %d]\n", pinf.ProtocolChain.ChainLen);
      for (i = 0; i < pinf.ProtocolChain.ChainLen; ++i)
      	printf ("    %d: %p\n", pinf.ProtocolChain.ChainEntries[i]);
      printf ("iVersion: %d\n", pinf.iVersion);
      printf ("iAddressFamily: %d\n", pinf.iAddressFamily);
      printf ("iMaxSockAddr: %d\n", pinf.iMaxSockAddr);
      printf ("iMinSockAddr: %d\n", pinf.iMinSockAddr);
      printf ("iSocketType: %d\n", pinf.iSocketType);
      printf ("iProtocol: %d\n", pinf.iProtocol);
      printf ("iProtocolMaxOffset: %d\n", pinf.iProtocolMaxOffset);
      printf ("iNetworkByteOrder: %d\n", pinf.iNetworkByteOrder);
      printf ("iSecurityScheme: %d\n", pinf.iSecurityScheme);
      printf ("dwMessageSize: %lu\n", pinf.dwMessageSize);
      printf ("dwProviderReserved: %lu\n", pinf.dwProviderReserved);
      printf ("szProtocol: %s\n", pinf.szProtocol);
      if (WSCGetProviderPath (&pinf.ProviderId, path, &len, &err))
	printf ("WSCGetProviderPath failed: %lu\n", err);
	printf ("ProviderPath: %ls\n", path);

  closesocket (sock_fd);
  WSACleanup ();
  return 0;
$ gcc-3 -mno-cygwin -g -o dup-sock dup-sock.c
$ ./dup-sock
[... output to be pasted ...]

And, please attach your cygcheck -s -v -r output per


Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

Problem reports:
Unsubscribe info:

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