From 188fc1cf6ee9905e765c62f5190caf9b95e4f77b Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 4 Feb 2013 12:04:20 +0000 Subject: * 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. --- winsup/cygwin/ChangeLog | 6 ++++++ winsup/cygwin/fhandler_socket.cc | 10 ++++++---- 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 + + * 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 * 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 (); -- cgit v1.2.3