Cygwin: fix memory corruption/SEGV if certain socket functions fail

Regression introduced with 2.11.0:

The failure paths in socket, socketpair and accept4 functions and
methods accidentally release *unused* cygheap_fdmanip objects.  The
subsequently called dtable::release method was designed to be called for
*used* cygheap_fdmanip objects only.  Using them on unused objects leads
to NULL pointer member dereferencing.

Worse, the inet/local accept4 methods only release the cygheap_fdmanip
object but neglect to delete the just created fhandler_socket_* object.

Fix this by removing the erroneous release calls in the aforementioned
failure paths and delete the fhandler_socket_* object in accept4 instead.

Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
Corinna Vinschen 2018-10-29 16:12:54 +01:00
parent af85fdd73f
commit 2bbe8697d8
5 changed files with 8 additions and 14 deletions

View File

@ -898,7 +898,7 @@ fhandler_socket_inet::accept4 (struct sockaddr *peer, int *len, int flags)
} }
} }
else else
fd.release (); delete sock;
} }
if (ret == -1) if (ret == -1)
::closesocket (res); ::closesocket (res);

View File

@ -988,7 +988,6 @@ fhandler_socket_local::accept4 (struct sockaddr *peer, int *len, int flags)
ret = sock->af_local_accept (); ret = sock->af_local_accept ();
if (ret == -1) if (ret == -1)
{ {
fd.release ();
delete sock; delete sock;
set_winsock_errno (); set_winsock_errno ();
return -1; return -1;
@ -1013,7 +1012,7 @@ fhandler_socket_local::accept4 (struct sockaddr *peer, int *len, int flags)
} }
} }
else else
fd.release (); delete sock;
} }
if (ret == -1) if (ret == -1)
::closesocket (res); ::closesocket (res);

View File

@ -1639,7 +1639,6 @@ fhandler_socket_unix::accept4 (struct sockaddr *peer, int *len, int flags)
create_shmem_failed: create_shmem_failed:
delete sock; delete sock;
} }
fd.release ();
} }
} }
/* Ouch! We can't handle the client if we couldn't /* Ouch! We can't handle the client if we couldn't

View File

@ -536,10 +536,7 @@ cygwin_socket (int af, int type, int protocol)
res = fd; res = fd;
} }
else else
{
delete fh; delete fh;
fd.release ();
}
} }
done: done:
@ -2314,10 +2311,7 @@ socketpair (int af, int type, int protocol, int sv[2])
cygheap_fdnew fd_out (fd_in, false); cygheap_fdnew fd_out (fd_in, false);
if (fd_out < 0) if (fd_out < 0)
{
fd_in.release ();
goto done; goto done;
}
fh_in = reinterpret_cast<fhandler_socket *> (build_fh_dev (*dev)); fh_in = reinterpret_cast<fhandler_socket *> (build_fh_dev (*dev));
fh_out = reinterpret_cast<fhandler_socket *> (build_fh_dev (*dev)); fh_out = reinterpret_cast<fhandler_socket *> (build_fh_dev (*dev));
@ -2343,8 +2337,6 @@ socketpair (int af, int type, int protocol, int sv[2])
{ {
delete fh_in; delete fh_in;
delete fh_out; delete fh_out;
fd_in.release ();
fd_out.release ();
} }
} }

View File

@ -14,3 +14,7 @@ Bug Fixes
- Fix a memory corruption when using pipes or FIFOs - Fix a memory corruption when using pipes or FIFOs
Addresses: https://cygwin.com/ml/cygwin-patches/2018-q4/msg00000.html Addresses: https://cygwin.com/ml/cygwin-patches/2018-q4/msg00000.html
- Fix potential memory corruption and SEGV if socket(2), socketpair(2),
accept(2), or accept4(2) fail.
Addresses: https://cygwin.com/ml/cygwin/2018-10/msg00229.html