On Fri, Sep 18, 2009 at 4:40 AM, Stephen Henson via RT <r...@openssl.org> wrote:
>> [openssl-...@openssl.org - Thu Sep 17 16:32:23 2009]:
>>
>> 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.
>>
>
> How portable is this code? Would it work on all systems not supporting
> IPv6 or should it all be surrounded by #if OPENSSL_USE_IPV6?
>
The patch basically did only one thing - use `struct sockaddr_storage'
instead of  `struct sockaddr', so this patch should work on all systems
that have `sockaddr_storage' defined - including various Linux distributions
Windows series and FreeBSD etc.

`sockaddr_storage' is introduced back to year 1999, in RFC2553:
"Basic Socket Interface Extensions for IPv6",
http://www.ietf.org/rfc/rfc2553.txt

"This data structure can simplify writing code portable across multiple address
families and platforms."

It seems that 'OPENSSL_USE_IPV6' is not in beta3?  I found your patch
which introduced this macro at Aug, 26.
http://groups.google.com/group/mailing.openssl.cvs/browse_thread/thread/9c801a7da9d62f04?pli=1

It's a pity that I can't find a non-IPv6 system around which I can test my
patch against.  (BeOS/Netware?)    To be really careful,  I modified my patch
to take care of 'OPENSSL_USE_IPV6', as shown below:

------------------------------<<begin>>------------------------------
--- a/crypto/bio/b_sock.c       Fri Sep 18 09:59:57 2009 +0800
+++ b/crypto/bio/b_sock.c       Fri Sep 18 10:59:08 2009 +0800
@@ -590,10 +590,19 @@
        return(1);
        }

+/* Use macro `openssl_sockaddr' to hide the difference between
+ * struct `sockaddr_storage' and `sockaddr'.
+ */
+#ifdef OPENSSL_USE_IPV6
+#  define openssl_sockaddr sockaddr_storage
+#  define sa_family ss_family
+#else
+#  define openssl_sockaddr sockaddr
+#endif
 int BIO_get_accept_socket(char *host, int bind_mode)
        {
        int ret=0;
-       struct sockaddr server,client;
+       struct openssl_sockaddr server,client;
        struct sockaddr_in *sa_in;
        int s=INVALID_SOCKET,cs;
        unsigned char ip[4];
@@ -665,7 +674,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);
@@ -778,6 +787,11 @@
                }
        return(s);
        }
+/* undefine the macro to avoid pollution. */
+#undef openssl_sockaddr
+#ifdef OPENSSL_USE_IPV6
+#undef sa_family
+#endif

 int BIO_accept(int sock, char **addr)
-------------------------------<<end>>-------------------------------

> Steve.
> --
> Dr Stephen N. Henson. OpenSSL project core developer.
> Commercial tech support now available see: http://www.openssl.org
>
>

-- 
Thanks,
Li Qun


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

Reply via email to