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:
parent
19a23dafba
commit
ff635f92c0
@ -6,6 +6,9 @@ Version 1.6.16
|
|||||||
|
|
||||||
Further measures against buffer overflows.
|
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.
|
Treat large argument as error in UpnpAddVirtualDir.
|
||||||
Do not clear buffer before snprintf.
|
Do not clear buffer before snprintf.
|
||||||
Clarify the last argument of GetDescDocumentAndURL has size LINE_SIZE.
|
Clarify the last argument of GetDescDocumentAndURL has size LINE_SIZE.
|
||||||
|
@ -1737,6 +1737,7 @@ int UpnpSearchAsync(
|
|||||||
{
|
{
|
||||||
struct Handle_Info *SInfo = NULL;
|
struct Handle_Info *SInfo = NULL;
|
||||||
char *Target = ( char * )Target_const;
|
char *Target = ( char * )Target_const;
|
||||||
|
int retVal;
|
||||||
|
|
||||||
if( UpnpSdkInit != 1 ) {
|
if( UpnpSdkInit != 1 ) {
|
||||||
return UPNP_E_FINISH;
|
return UPNP_E_FINISH;
|
||||||
@ -1759,7 +1760,9 @@ int UpnpSearchAsync(
|
|||||||
}
|
}
|
||||||
|
|
||||||
HandleUnlock();
|
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__,
|
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
|
||||||
"Exiting UpnpSearchAsync \n" );
|
"Exiting UpnpSearchAsync \n" );
|
||||||
|
@ -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
|
* \brief Creates a HTTP search request packet depending on the input
|
||||||
* parameter.
|
* parameter.
|
||||||
*/
|
*/
|
||||||
static void CreateClientRequestPacket(
|
static int CreateClientRequestPacket(
|
||||||
/*! [in] Output string in HTTP format. */
|
/*! [in,out] Output string in HTTP format. */
|
||||||
IN char *RqstBuf,
|
INOUT char *RqstBuf,
|
||||||
|
/*! [in] RqstBuf size. */
|
||||||
|
IN size_t RqstBufSize,
|
||||||
/*! [in] Search Target. */
|
/*! [in] Search Target. */
|
||||||
IN int Mx,
|
IN int Mx,
|
||||||
/*! [in] Number of seconds to wait to collect all the responses. */
|
/*! [in] Number of seconds to wait to collect all the responses. */
|
||||||
@ -318,68 +320,121 @@ static void CreateClientRequestPacket(
|
|||||||
/*! [in] search address family. */
|
/*! [in] search address family. */
|
||||||
IN int AddressFamily)
|
IN int AddressFamily)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
char TempBuf[COMMAND_LEN];
|
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));
|
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) {
|
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);
|
SSDP_PORT);
|
||||||
} else if (AddressFamily == AF_INET6) {
|
} 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);
|
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, 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) {
|
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);
|
strcat(RqstBuf, TempBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SearchTarget != NULL) {
|
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);
|
strcat(RqstBuf, TempBuf);
|
||||||
}
|
}
|
||||||
|
if (RqstBufSize <= strlen(RqstBuf) + strlen("\r\n"))
|
||||||
|
return UPNP_E_BUFFER_TOO_SMALL;
|
||||||
strcat(RqstBuf, "\r\n");
|
strcat(RqstBuf, "\r\n");
|
||||||
|
|
||||||
|
return UPNP_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief
|
* \brief
|
||||||
*/
|
*/
|
||||||
static void CreateClientRequestPacketUlaGua(
|
static int CreateClientRequestPacketUlaGua(
|
||||||
/*! [in] . */
|
/*! [in,out] . */
|
||||||
char *RqstBuf,
|
char *RqstBuf,
|
||||||
/*! [in] . */
|
/*! [in] . */
|
||||||
|
size_t RqstBufSize,
|
||||||
|
/*! [in] . */
|
||||||
int Mx,
|
int Mx,
|
||||||
/*! [in] . */
|
/*! [in] . */
|
||||||
char *SearchTarget,
|
char *SearchTarget,
|
||||||
/*! [in] . */
|
/*! [in] . */
|
||||||
int AddressFamily)
|
int AddressFamily)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
char TempBuf[COMMAND_LEN];
|
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));
|
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) {
|
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);
|
SSDP_PORT);
|
||||||
} else if (AddressFamily == AF_INET6) {
|
} 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);
|
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, 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) {
|
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);
|
strcat(RqstBuf, TempBuf);
|
||||||
}
|
}
|
||||||
if (SearchTarget) {
|
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);
|
strcat(RqstBuf, TempBuf);
|
||||||
}
|
}
|
||||||
|
if (RqstBufSize <= strlen(RqstBuf) + strlen("\r\n"))
|
||||||
|
return UPNP_E_BUFFER_TOO_SMALL;
|
||||||
strcat(RqstBuf, "\r\n");
|
strcat(RqstBuf, "\r\n");
|
||||||
|
|
||||||
|
return UPNP_E_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -452,6 +507,7 @@ int SearchByTarget(int Mx, char *St, void *Cookie)
|
|||||||
enum SsdpSearchType requestType;
|
enum SsdpSearchType requestType;
|
||||||
unsigned long addrv4 = inet_addr(gIF_IPV4);
|
unsigned long addrv4 = inet_addr(gIF_IPV4);
|
||||||
SOCKET max_fd = 0;
|
SOCKET max_fd = 0;
|
||||||
|
int retVal;
|
||||||
|
|
||||||
/*ThreadData *ThData; */
|
/*ThreadData *ThData; */
|
||||||
ThreadPoolJob job;
|
ThreadPoolJob job;
|
||||||
@ -468,9 +524,15 @@ int SearchByTarget(int Mx, char *St, void *Cookie)
|
|||||||
timeTillRead = MIN_SEARCH_TIME;
|
timeTillRead = MIN_SEARCH_TIME;
|
||||||
else if (timeTillRead > MAX_SEARCH_TIME)
|
else if (timeTillRead > MAX_SEARCH_TIME)
|
||||||
timeTillRead = MAX_SEARCH_TIME;
|
timeTillRead = MAX_SEARCH_TIME;
|
||||||
CreateClientRequestPacket(ReqBufv4, timeTillRead, St, AF_INET);
|
retVal = CreateClientRequestPacket(ReqBufv4, sizeof(ReqBufv4), timeTillRead, St, AF_INET);
|
||||||
CreateClientRequestPacket(ReqBufv6, timeTillRead, St, AF_INET6);
|
if (retVal != UPNP_E_SUCCESS)
|
||||||
CreateClientRequestPacketUlaGua(ReqBufv6UlaGua, timeTillRead, St, AF_INET6);
|
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));
|
memset(&__ss_v4, 0, sizeof(__ss_v4));
|
||||||
destAddr4->sin_family = AF_INET;
|
destAddr4->sin_family = AF_INET;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user