summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-02-04 12:04:20 +0000
committerCorinna Vinschen <corinna@vinschen.de>2013-02-04 12:04:20 +0000
commit188fc1cf6ee9905e765c62f5190caf9b95e4f77b (patch)
treefc67a7b842db224069a6f9915d8960c69d8b3250
parentdb7922e5bcc07bd95e1b5e9de758712322c3fa01 (diff)
downloadcygnal-188fc1cf6ee9905e765c62f5190caf9b95e4f77b.tar.gz
cygnal-188fc1cf6ee9905e765c62f5190caf9b95e4f77b.tar.bz2
cygnal-188fc1cf6ee9905e765c62f5190caf9b95e4f77b.zip
* fhandler_socket.cc (fhandler_socket::bind): Fix length check of
AF_LOCAL filename so it never accesses memory beyond namelen. Also make sure filename is NUL-terminated.
-rw-r--r--winsup/cygwin/ChangeLog6
-rw-r--r--winsup/cygwin/fhandler_socket.cc10
2 files changed, 12 insertions, 4 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index a50875fca..2eb9c45a9 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,9 @@
+2013-02-04 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (fhandler_socket::bind): Fix length check of
+ AF_LOCAL filename so it never accesses memory beyond namelen. Also
+ make sure filename is NUL-terminated.
+
2013-01-31 Christopher Faylor <me.cygwin2013@cgf.cx>
* DevNotes: Add entry cgf-000022.
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index 6625eef05..6f13e51ce 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -900,17 +900,19 @@ fhandler_socket::bind (const struct sockaddr *name, int namelen)
{
#define un_addr ((struct sockaddr_un *) name)
struct sockaddr_in sin;
- int len = sizeof sin;
+ int len = namelen - offsetof (struct sockaddr_un, sun_path);
- if (strlen (un_addr->sun_path) >= UNIX_PATH_LEN)
+ /* Check that name is within bounds and NUL-terminated. */
+ if (len <= 1 || len > UNIX_PATH_LEN
+ || !memchr (un_addr->sun_path, '\0', len))
{
- set_errno (ENAMETOOLONG);
+ set_errno (len < 1 ? EINVAL : ENAMETOOLONG);
goto out;
}
sin.sin_family = AF_INET;
sin.sin_port = 0;
sin.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
- if (::bind (get_socket (), (sockaddr *) &sin, len))
+ if (::bind (get_socket (), (sockaddr *) &sin, len = sizeof sin))
{
syscall_printf ("AF_LOCAL: bind failed");
set_winsock_errno ();