Detect overflow in CreateClientRequestPacket(UlaGua).

Pass output buffer size to CreateClientRequestPacket(UlaGua)
from SearchByTarget and detect overflow.
Handle SearchByTarget error in UpnpSearchAsync.
(cherry picked from commit ff635f92c08cf8f7ebca973450bd79feacb2e0b1)
This commit is contained in:
Yoichi NAKAYAMA 2012-03-11 02:47:58 +09:00 committed by Marcelo Roberto Jimenez
parent 1ed33f3c5b
commit 6ba4181fe6
3 changed files with 89 additions and 21 deletions

View File

@ -322,6 +322,9 @@ 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.

View File

@ -1770,6 +1770,7 @@ int UpnpSearchAsync(
{
struct Handle_Info *SInfo = NULL;
char *Target = ( char * )Target_const;
int retVal;
if( UpnpSdkInit != 1 ) {
return UPNP_E_FINISH;
@ -1792,7 +1793,9 @@ int UpnpSearchAsync(
}
HandleUnlock();
SearchByTarget( Mx, Target, ( void * )Cookie_const );
retVal = SearchByTarget( Mx, Target, ( void * )Cookie_const );
if (retVal != 1)
return retVal;
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Exiting UpnpSearchAsync \n" );

View File

@ -316,9 +316,11 @@ end_ssdp_handle_ctrlpt_msg:
* \brief Creates a HTTP search request packet depending on the input
* parameter.
*/
static void CreateClientRequestPacket(
/*! [in] Output string in HTTP format. */
IN char *RqstBuf,
static int CreateClientRequestPacket(
/*! [in,out] Output string in HTTP format. */
INOUT char *RqstBuf,
/*! [in] RqstBuf size. */
IN size_t RqstBufSize,
/*! [in] Search Target. */
IN int Mx,
/*! [in] Number of seconds to wait to collect all the responses. */
@ -326,68 +328,121 @@ static void CreateClientRequestPacket(
/*! [in] search address family. */
IN int AddressFamily)
{
int rc;
char TempBuf[COMMAND_LEN];
const char *command = "M-SEARCH * HTTP/1.1\r\n";
const char *man = "MAN: \"ssdp:discover\"\r\n";
memset(TempBuf, 0, sizeof(TempBuf));
strcpy(RqstBuf, "M-SEARCH * HTTP/1.1\r\n");
if (RqstBufSize <= strlen(command))
return UPNP_E_INTERNAL_ERROR;
strcpy(RqstBuf, command);
if (AddressFamily == AF_INET) {
snprintf(TempBuf, sizeof(TempBuf), "HOST: %s:%d\r\n", SSDP_IP,
rc = snprintf(TempBuf, sizeof(TempBuf), "HOST: %s:%d\r\n", SSDP_IP,
SSDP_PORT);
} else if (AddressFamily == AF_INET6) {
snprintf(TempBuf, sizeof(TempBuf), "HOST: [%s]:%d\r\n",
rc = snprintf(TempBuf, sizeof(TempBuf), "HOST: [%s]:%d\r\n",
SSDP_IPV6_LINKLOCAL, SSDP_PORT);
}
if (rc < 0 || (unsigned int) rc >= sizeof(TempBuf))
return UPNP_E_INTERNAL_ERROR;
if (RqstBufSize <= strlen(RqstBuf) + strlen(TempBuf))
return UPNP_E_BUFFER_TOO_SMALL;
strcat(RqstBuf, TempBuf);
strcat(RqstBuf, "MAN: \"ssdp:discover\"\r\n");
if (RqstBufSize <= strlen(RqstBuf) + strlen(man))
return UPNP_E_BUFFER_TOO_SMALL;
strcat(RqstBuf, man);
if (Mx > 0) {
snprintf(TempBuf, sizeof(TempBuf), "MX: %d\r\n", Mx);
rc = snprintf(TempBuf, sizeof(TempBuf), "MX: %d\r\n", Mx);
if (rc < 0 || (unsigned int) rc >= sizeof(TempBuf))
return UPNP_E_INTERNAL_ERROR;
if (RqstBufSize <= strlen(RqstBuf) + strlen(TempBuf))
return UPNP_E_BUFFER_TOO_SMALL;
strcat(RqstBuf, TempBuf);
}
if (SearchTarget != NULL) {
snprintf(TempBuf, sizeof(TempBuf), "ST: %s\r\n", SearchTarget);
rc = snprintf(TempBuf, sizeof(TempBuf), "ST: %s\r\n", SearchTarget);
if (rc < 0 || (unsigned int) rc >= sizeof(TempBuf))
return UPNP_E_INTERNAL_ERROR;
if (RqstBufSize <= strlen(RqstBuf) + strlen(TempBuf))
return UPNP_E_BUFFER_TOO_SMALL;
strcat(RqstBuf, TempBuf);
}
if (RqstBufSize <= strlen(RqstBuf) + strlen("\r\n"))
return UPNP_E_BUFFER_TOO_SMALL;
strcat(RqstBuf, "\r\n");
return UPNP_E_SUCCESS;
}
/*!
* \brief
*/
static void CreateClientRequestPacketUlaGua(
/*! [in] . */
static int CreateClientRequestPacketUlaGua(
/*! [in,out] . */
char *RqstBuf,
/*! [in] . */
size_t RqstBufSize,
/*! [in] . */
int Mx,
/*! [in] . */
char *SearchTarget,
/*! [in] . */
int AddressFamily)
{
int rc;
char TempBuf[COMMAND_LEN];
const char *command = "M-SEARCH * HTTP/1.1\r\n";
const char *man = "MAN: \"ssdp:discover\"\r\n";
memset(TempBuf, 0, sizeof(TempBuf));
strcpy(RqstBuf, "M-SEARCH * HTTP/1.1\r\n");
if (RqstBufSize <= strlen(command))
return UPNP_E_INTERNAL_ERROR;
strcpy(RqstBuf, command);
if (AddressFamily == AF_INET) {
snprintf(TempBuf, sizeof(TempBuf), "HOST: %s:%d\r\n", SSDP_IP,
rc = snprintf(TempBuf, sizeof(TempBuf), "HOST: %s:%d\r\n", SSDP_IP,
SSDP_PORT);
} else if (AddressFamily == AF_INET6) {
snprintf(TempBuf, sizeof(TempBuf), "HOST: [%s]:%d\r\n",
rc = snprintf(TempBuf, sizeof(TempBuf), "HOST: [%s]:%d\r\n",
SSDP_IPV6_SITELOCAL, SSDP_PORT);
}
if (rc < 0 || (unsigned int) rc >= sizeof(TempBuf))
return UPNP_E_INTERNAL_ERROR;
if (RqstBufSize <= strlen(RqstBuf) + strlen(TempBuf))
return UPNP_E_BUFFER_TOO_SMALL;
strcat(RqstBuf, TempBuf);
strcat(RqstBuf, "MAN: \"ssdp:discover\"\r\n");
if (RqstBufSize <= strlen(RqstBuf) + strlen(man))
return UPNP_E_BUFFER_TOO_SMALL;
strcat(RqstBuf, man);
if (Mx > 0) {
snprintf(TempBuf, sizeof(TempBuf), "MX: %d\r\n", Mx);
rc = snprintf(TempBuf, sizeof(TempBuf), "MX: %d\r\n", Mx);
if (rc < 0 || (unsigned int) rc >= sizeof(TempBuf))
return UPNP_E_INTERNAL_ERROR;
if (RqstBufSize <= strlen(RqstBuf) + strlen(TempBuf))
return UPNP_E_BUFFER_TOO_SMALL;
strcat(RqstBuf, TempBuf);
}
if (SearchTarget) {
snprintf(TempBuf, sizeof(TempBuf), "ST: %s\r\n", SearchTarget);
rc = snprintf(TempBuf, sizeof(TempBuf), "ST: %s\r\n", SearchTarget);
if (rc < 0 || (unsigned int) rc >= sizeof(TempBuf))
return UPNP_E_INTERNAL_ERROR;
if (RqstBufSize <= strlen(RqstBuf) + strlen(TempBuf))
return UPNP_E_BUFFER_TOO_SMALL;
strcat(RqstBuf, TempBuf);
}
if (RqstBufSize <= strlen(RqstBuf) + strlen("\r\n"))
return UPNP_E_BUFFER_TOO_SMALL;
strcat(RqstBuf, "\r\n");
return UPNP_E_SUCCESS;
}
/*!
@ -460,6 +515,7 @@ int SearchByTarget(int Mx, char *St, void *Cookie)
enum SsdpSearchType requestType;
unsigned long addrv4 = inet_addr(gIF_IPV4);
SOCKET max_fd = 0;
int retVal;
/*ThreadData *ThData; */
ThreadPoolJob job;
@ -476,9 +532,15 @@ int SearchByTarget(int Mx, char *St, void *Cookie)
timeTillRead = MIN_SEARCH_TIME;
else if (timeTillRead > MAX_SEARCH_TIME)
timeTillRead = MAX_SEARCH_TIME;
CreateClientRequestPacket(ReqBufv4, timeTillRead, St, AF_INET);
CreateClientRequestPacket(ReqBufv6, timeTillRead, St, AF_INET6);
CreateClientRequestPacketUlaGua(ReqBufv6UlaGua, timeTillRead, St, AF_INET6);
retVal = CreateClientRequestPacket(ReqBufv4, sizeof(ReqBufv4), timeTillRead, St, AF_INET);
if (retVal != UPNP_E_SUCCESS)
return retVal;
retVal = CreateClientRequestPacket(ReqBufv6, sizeof(ReqBufv6), timeTillRead, St, AF_INET6);
if (retVal != UPNP_E_SUCCESS)
return retVal;
retVal = CreateClientRequestPacketUlaGua(ReqBufv6UlaGua, sizeof(ReqBufv6UlaGua), timeTillRead, St, AF_INET6);
if (retVal != UPNP_E_SUCCESS)
return retVal;
memset(&__ss_v4, 0, sizeof(__ss_v4));
destAddr4->sin_family = AF_INET;