[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openssl-dev
Subject:    [PATCH][Beta3] Fix IPv6 handling in BIO_get_accept_socket()
From:       David Lee <live4thee () gmail ! com>
Date:       2009-08-21 6:13:30
Message-ID: 8f62e1cd0908202313x7cd809c8oe6c1f8ff99ddef5a () mail ! gmail ! com
[Download RAW message or body]

Hi, list
I downloaded OpenSSL 1.0 beta3 and found a bug in the function
BIO_get_accept_socket(), when dealing with an IPv6 address.

The line below copies the content of `res->ai_addr' to `server', but
sizeof(server) = 16, while for IPv6 address, res->ai_addrlen is 28.
i.e, sizeof(struct sockadr_in6).  The missing 12 bytes will cause
the later bind() always fail.

 struct sockaddr server,client;
 server = *res->ai_addr;

To fix it, I use the type `struct sockaddr_storage' to hold the
address information so that its storage can satisfy any type of socket
address, for example:

 struct sockaddr_storage server,client;
 memcpy(&server, res->ai_addr, res->ai_addrlen);

Pls see the patch in attachment for details.

-- 
Thanks,
Li Qun

["fix-ipv6-handling.patch" (application/octet-stream)]

diff -r 97f29e34d19e crypto/bio/b_sock.c
--- a/crypto/bio/b_sock.c	Fri Aug 21 06:15:56 2009 -0400
+++ b/crypto/bio/b_sock.c	Fri Aug 21 10:03:36 2009 -0400
@@ -593,7 +593,7 @@
 int BIO_get_accept_socket(char *host, int bind_mode)
 	{
 	int ret=0;
-	struct sockaddr server,client;
+	struct sockaddr_storage server,client;
 	struct sockaddr_in *sa_in;
 	int s=INVALID_SOCKET,cs;
 	unsigned char ip[4];
@@ -665,7 +665,7 @@
 		}
 
 	if ((*p_getaddrinfo.f)(h,p,&hint,&res)) break;
-	server = *res->ai_addr;
+	memcpy(&server, res->ai_addr, res->ai_addrlen);
 	(*p_freeaddrinfo.f)(res);
 	goto again;
 	} while (0);
@@ -692,7 +692,7 @@
 		}
 
 again:
-	s=socket(server.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
+	s=socket(server.ss_family,SOCK_STREAM,SOCKET_PROTOCOL);
 	if (s == INVALID_SOCKET)
 		{
 		SYSerr(SYS_F_SOCKET,get_last_socket_error());
@@ -710,7 +710,7 @@
 		bind_mode=BIO_BIND_NORMAL;
 		}
 #endif
-	if (bind(s,&server,sizeof(server)) == -1)
+	if (bind(s,(struct sockaddr*)&server,sizeof(server)) == -1)
 		{
 #ifdef SO_REUSEADDR
 		err_num=get_last_socket_error();
@@ -721,7 +721,7 @@
 			if (h == NULL || strcmp(h,"*") == 0)
 				{
 #ifdef AF_INET6
-				if (client.sa_family == AF_INET6)
+				if (client.ss_family == AF_INET6)
 					{
 					struct sockaddr_in6 *sin6 =
 						(struct sockaddr_in6 *)&client;
@@ -730,7 +730,7 @@
 					}
 				else
 #endif
-				if (client.sa_family == AF_INET)
+				if (client.ss_family == AF_INET)
 					{
 					struct sockaddr_in *sin4 =
 						(struct sockaddr_in *)&client;
@@ -738,7 +738,7 @@
 					}
 				else	goto err;
 				}
-			cs=socket(client.sa_family,SOCK_STREAM,SOCKET_PROTOCOL);
+			cs=socket(client.ss_family,SOCK_STREAM,SOCKET_PROTOCOL);
 			if (cs != INVALID_SOCKET)
 				{
 				int ii;

______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       openssl-dev@openssl.org
Automated List Manager                           majordomo@openssl.org

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic