Detect overflow in CreateClientRequestPacket(UlaGua).

Pass output buffer size to CreateClientRequestPacket(UlaGua)
from SearchByTarget and detect overflow.
Handle SearchByTarget error in UpnpSearchAsync.
This commit is contained in:
Yoichi NAKAYAMA 2012-03-11 02:47:58 +09:00
parent 19a23dafba
commit ff635f92c0
3 changed files with 89 additions and 21 deletions

View File

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

@ -1737,6 +1737,7 @@ int UpnpSearchAsync(
{
struct Handle_Info *SInfo = NULL;
char *Target = ( char * )Target_const;
int retVal;
if( UpnpSdkInit != 1 ) {
return UPNP_E_FINISH;
@ -1759,7 +1760,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

@ -308,9 +308,11 @@ void ssdp_handle_ctrlpt_msg(http_message_t *hmsg, struct sockaddr_storage *dest_
* \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. */
@ -318,68 +320,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;
}
/*!
@ -452,6 +507,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;
@ -468,9 +524,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;