Detect overflow in addrToString called from configure_urlbase.

Pass output buffer size to addrToString and detect overflow.
Handle addrToString error in configure_urlbase.
(cherry picked from commit 56b44fee914738eb9e8bddc5fce768e2dbc4db12)
This commit is contained in:
Yoichi NAKAYAMA 2012-03-11 03:25:41 +09:00 committed by Marcelo Roberto Jimenez
parent 6ba4181fe6
commit da1dec9ee5
2 changed files with 28 additions and 16 deletions

View File

@ -322,13 +322,15 @@ Version 1.6.16
Further measures against buffer overflows. Further measures against buffer overflows.
Pass output buffer size to CreateClientRequestPacket(UlaGua) * Pass output buffer size to CreateClientRequestPacket(UlaGua)
from SearchByTarget and detect overflow. from SearchByTarget and detect overflow.
Handle SearchByTarget error in UpnpSearchAsync. * Handle SearchByTarget error in UpnpSearchAsync.
Treat large argument as error in UpnpAddVirtualDir. * Pass output buffer size to addrToString and detect overflow.
Do not clear buffer before snprintf. * Handle addrToString error in configure_urlbase.
Clarify the last argument of GetDescDocumentAndURL has size LINE_SIZE. * Treat large argument as error in UpnpAddVirtualDir.
For inet_ntop, use buffer with size INET6_ADDRSTRLEN or INET_ADDRSTRLEN. * Do not clear buffer before snprintf.
* Clarify the last argument of GetDescDocumentAndURL has size LINE_SIZE.
* For inet_ntop, use buffer with size INET6_ADDRSTRLEN or INET_ADDRSTRLEN.
2012-03-10 Yoichi NAKAYAMA <yoichi.nakayama(at)gmail.com> 2012-03-10 Yoichi NAKAYAMA <yoichi.nakayama(at)gmail.com>

View File

@ -50,6 +50,7 @@
#include <stdio.h> #include <stdio.h>
#ifdef WIN32 #ifdef WIN32
#define snprintf _snprintf
#else #else
#include <sys/types.h> #include <sys/types.h>
#endif #endif
@ -63,31 +64,39 @@
* Parameters : * Parameters :
* IN const struct sockaddr* addr ; socket address object with * IN const struct sockaddr* addr ; socket address object with
* the IP Address and port information * the IP Address and port information
* OUT char ipaddr_port[] ; character array which will hold the * OUT char ipaddr_port ; character array which will hold the
* IP Address in a string format. * IP Address in a string format.
* IN size_t ipaddr_port_size ; ipaddr_port buffer size
* *
* Description : Converts an Internet address to a string and stores it * Description : Converts an Internet address to a string and stores it
* a buffer. * a buffer.
* *
* Return : void ; * Return : int ;
* UPNP_E_SUCCESS - On Success.
* UPNP_E_BUFFER_TOO_SMALL - Given buffer doesn't have enough size.
* *
* Note : * Note :
************************************************************************/ ************************************************************************/
static UPNP_INLINE void static UPNP_INLINE int
addrToString( IN const struct sockaddr *addr, addrToString( IN const struct sockaddr *addr,
OUT char ipaddr_port[] ) OUT char *ipaddr_port,
IN size_t ipaddr_port_size )
{ {
char buf_ntop[INET6_ADDRSTRLEN]; char buf_ntop[INET6_ADDRSTRLEN];
int rc;
if( addr->sa_family == AF_INET ) { if( addr->sa_family == AF_INET ) {
struct sockaddr_in* sa4 = (struct sockaddr_in*)addr; struct sockaddr_in* sa4 = (struct sockaddr_in*)addr;
inet_ntop(AF_INET, &sa4->sin_addr, buf_ntop, sizeof(buf_ntop) ); inet_ntop(AF_INET, &sa4->sin_addr, buf_ntop, sizeof(buf_ntop) );
sprintf( ipaddr_port, "%s:%d", buf_ntop, ntohs( sa4->sin_port ) ); rc = snprintf( ipaddr_port, ipaddr_port_size, "%s:%d", buf_ntop, ntohs( sa4->sin_port ) );
} else if( addr->sa_family == AF_INET6 ) { } else if( addr->sa_family == AF_INET6 ) {
struct sockaddr_in6* sa6 = (struct sockaddr_in6*)addr; struct sockaddr_in6* sa6 = (struct sockaddr_in6*)addr;
inet_ntop(AF_INET6, &sa6->sin6_addr, buf_ntop, sizeof(buf_ntop) ); inet_ntop(AF_INET6, &sa6->sin6_addr, buf_ntop, sizeof(buf_ntop) );
sprintf( ipaddr_port, "[%s]:%d", buf_ntop, ntohs( sa6->sin6_port ) ); rc = snprintf( ipaddr_port, ipaddr_port_size, "[%s]:%d", buf_ntop, ntohs( sa6->sin6_port ) );
} }
if (rc < 0 || (unsigned int) rc >= ipaddr_port_size)
return UPNP_E_BUFFER_TOO_SMALL;
return UPNP_E_SUCCESS;
} }
/************************************************************************ /************************************************************************
@ -376,10 +385,11 @@ configure_urlbase( INOUT IXML_Document * doc,
int err_code; int err_code;
char ipaddr_port[LINE_SIZE]; char ipaddr_port[LINE_SIZE];
err_code = UPNP_E_OUTOF_MEMORY; /* default error */
/* get IP address and port */ /* get IP address and port */
addrToString( serverAddr, ipaddr_port ); err_code = addrToString( serverAddr, ipaddr_port, sizeof(ipaddr_port) );
if ( err_code != UPNP_E_SUCCESS ) {
goto error_handler;
}
/* config url-base in 'doc' */ /* config url-base in 'doc' */
err_code = config_description_doc( doc, ipaddr_port, &root_path ); err_code = config_description_doc( doc, ipaddr_port, &root_path );