From 7655044dd3fb8dd9862af2e8acd747d6f9168d8e Mon Sep 17 00:00:00 2001 From: Andy Polyakov Date: Tue, 19 Jun 2012 12:36:00 +0000 Subject: [PATCH] bss_dgram.c: fix bugs [from HEAD]. PR: 2833 --- crypto/bio/bss_dgram.c | 70 ++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c index 46cbe8a407..b167bd03b2 100644 --- a/crypto/bio/bss_dgram.c +++ b/crypto/bio/bss_dgram.c @@ -77,11 +77,11 @@ #define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0 #endif -#ifdef OPENSSL_SYS_LINUX +#if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU) #define IP_MTU 14 /* linux is lame */ #endif -#ifdef __FreeBSD__ +#if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED) /* Standard definition causes type-punning problems. */ #undef IN6_IS_ADDR_V4MAPPED #define s6_addr32 __u6_addr.__u6_addr32 @@ -265,7 +265,7 @@ static void dgram_adjust_rcv_timeout(BIO *b) { #if defined(SO_RCVTIMEO) bio_dgram_data *data = (bio_dgram_data *)b->ptr; - int sz = sizeof(int); + union { size_t s; int i; } sz = {0}; /* Is a timer active? */ if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) @@ -275,6 +275,8 @@ static void dgram_adjust_rcv_timeout(BIO *b) /* Read current socket timeout */ #ifdef OPENSSL_SYS_WINDOWS int timeout; + + sz.i = sizeof(timeout); if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, &sz) < 0) { perror("getsockopt"); } @@ -284,9 +286,12 @@ static void dgram_adjust_rcv_timeout(BIO *b) data->socket_timeout.tv_usec = (timeout % 1000) * 1000; } #else + sz.i = sizeof(data->socket_timeout); if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout), (void *)&sz) < 0) { perror("getsockopt"); } + else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0) + OPENSSL_assert(sz.s<=sizeof(data->socket_timeout)); #endif /* Get current time */ @@ -455,11 +460,10 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) int *ip; struct sockaddr *to = NULL; bio_dgram_data *data = NULL; -#if defined(IP_MTU_DISCOVER) || defined(IP_MTU) - long sockopt_val = 0; - unsigned int sockopt_len = 0; -#endif -#ifdef OPENSSL_SYS_LINUX + int sockopt_val = 0; +#if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU)) + socklen_t sockopt_len; /* assume that system supporting IP_MTU is + * modern enough to define socklen_t */ socklen_t addr_len; union { struct sockaddr sa; @@ -541,7 +545,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) break; /* (Linux)kernel sets DF bit on outgoing IP packets */ case BIO_CTRL_DGRAM_MTU_DISCOVER: -#ifdef OPENSSL_SYS_LINUX +#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) addr_len = (socklen_t)sizeof(addr); memset((void *)&addr, 0, sizeof(addr)); if (getsockname(b->num, &addr.sa, &addr_len) < 0) @@ -549,7 +553,6 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) ret = 0; break; } - sockopt_len = sizeof(sockopt_val); switch (addr.sa.sa_family) { case AF_INET: @@ -558,7 +561,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) &sockopt_val, sizeof(sockopt_val))) < 0) perror("setsockopt"); break; -#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) +#if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) case AF_INET6: sockopt_val = IPV6_PMTUDISC_DO; if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER, @@ -575,7 +578,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) break; #endif case BIO_CTRL_DGRAM_QUERY_MTU: -#ifdef OPENSSL_SYS_LINUX +#if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU) addr_len = (socklen_t)sizeof(addr); memset((void *)&addr, 0, sizeof(addr)); if (getsockname(b->num, &addr.sa, &addr_len) < 0) @@ -737,10 +740,13 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) #endif break; case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: -#ifdef OPENSSL_SYS_WINDOWS { - int timeout, sz = sizeof(timeout); + union { size_t s; int i; } sz = {0}; +#ifdef OPENSSL_SYS_WINDOWS + int timeout; struct timeval *tv = (struct timeval *)ptr; + + sz.i = sizeof(timeout); if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, &sz) < 0) { perror("getsockopt"); ret = -1; } @@ -750,12 +756,20 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) tv->tv_usec = (timeout % 1000) * 1000; ret = sizeof(*tv); } - } #else + sz.i = sizeof(struct timeval); if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, - ptr, (void *)&ret) < 0) + ptr, (void *)&sz) < 0) { perror("getsockopt"); ret = -1; } + else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0) + { + OPENSSL_assert(sz.s<=sizeof(struct timeval)); + ret = (int)sz.s; + } + else + ret = sz.i; #endif + } break; #endif #if defined(SO_SNDTIMEO) @@ -775,10 +789,13 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) #endif break; case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: -#ifdef OPENSSL_SYS_WINDOWS { - int timeout, sz = sizeof(timeout); + union { size_t s; int i; } sz = {0}; +#ifdef OPENSSL_SYS_WINDOWS + int timeout; struct timeval *tv = (struct timeval *)ptr; + + sz.i = sizeof(timeout); if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, (void*)&timeout, &sz) < 0) { perror("getsockopt"); ret = -1; } @@ -790,10 +807,19 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) } } #else + sz.i = sizeof(struct timeval); if ( getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, - ptr, (void *)&ret) < 0) + ptr, (void *)&sz) < 0) { perror("getsockopt"); ret = -1; } + else if (sizeof(sz.s)!=sizeof(sz.i) && sz.i==0) + { + OPENSSL_assert(sz.s<=sizeof(struct timeval)); + ret = (int)sz.s; + } + else + ret = sz.i; #endif + } break; #endif case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP: @@ -965,7 +991,6 @@ static int dgram_sctp_free(BIO *a) #ifdef SCTP_AUTHENTICATION_EVENT void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp) { - unsigned int sockopt_len = 0; int ret; struct sctp_authkey_event* authkeyevent = &snp->sn_auth_event; @@ -975,9 +1000,8 @@ void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification *snp) /* delete key */ authkeyid.scact_keynumber = authkeyevent->auth_keynumber; - sockopt_len = sizeof(struct sctp_authkeyid); ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, - &authkeyid, sockopt_len); + &authkeyid, sizeof(struct sctp_authkeyid)); } } #endif @@ -1308,7 +1332,7 @@ static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) { long ret=1; bio_dgram_sctp_data *data = NULL; - unsigned int sockopt_len = 0; + socklen_t sockopt_len = 0; struct sctp_authkeyid authkeyid; struct sctp_authkey *authkey; -- 2.25.1