From da1dec9ee53e5878a9339909539ca13e341eef00 Mon Sep 17 00:00:00 2001 From: Yoichi NAKAYAMA Date: Sun, 11 Mar 2012 03:25:41 +0900 Subject: [PATCH] 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) --- ChangeLog | 16 +++++++++------- upnp/src/urlconfig/urlconfig.c | 28 +++++++++++++++++++--------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/ChangeLog b/ChangeLog index b358bd8..9ddac6f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -322,13 +322,15 @@ Version 1.6.16 Further measures against buffer overflows. - Pass output buffer size to CreateClientRequestPacket(UlaGua) - from SearchByTarget and detect overflow. - Handle SearchByTarget error in UpnpSearchAsync. - Treat large argument as error in UpnpAddVirtualDir. - 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. + * Pass output buffer size to CreateClientRequestPacket(UlaGua) + from SearchByTarget and detect overflow. + * Handle SearchByTarget error in UpnpSearchAsync. + * Pass output buffer size to addrToString and detect overflow. + * Handle addrToString error in configure_urlbase. + * Treat large argument as error in UpnpAddVirtualDir. + * 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 diff --git a/upnp/src/urlconfig/urlconfig.c b/upnp/src/urlconfig/urlconfig.c index 7ccb146..5cf6654 100644 --- a/upnp/src/urlconfig/urlconfig.c +++ b/upnp/src/urlconfig/urlconfig.c @@ -50,6 +50,7 @@ #include #ifdef WIN32 + #define snprintf _snprintf #else #include #endif @@ -63,31 +64,39 @@ * Parameters : * IN const struct sockaddr* addr ; socket address object with * 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. +* IN size_t ipaddr_port_size ; ipaddr_port buffer size * * Description : Converts an Internet address to a string and stores it * a buffer. * -* Return : void ; +* Return : int ; +* UPNP_E_SUCCESS - On Success. +* UPNP_E_BUFFER_TOO_SMALL - Given buffer doesn't have enough size. * * Note : ************************************************************************/ -static UPNP_INLINE void +static UPNP_INLINE int 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]; + int rc; if( addr->sa_family == AF_INET ) { struct sockaddr_in* sa4 = (struct sockaddr_in*)addr; 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 ) { struct sockaddr_in6* sa6 = (struct sockaddr_in6*)addr; 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; char ipaddr_port[LINE_SIZE]; - err_code = UPNP_E_OUTOF_MEMORY; /* default error */ - /* 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' */ err_code = config_description_doc( doc, ipaddr_port, &root_path );