prevent infinite loop in upnpDiscover()

fixes #488
This commit is contained in:
Thomas Bernard 2020-09-23 00:41:26 +02:00
parent a21a35e003
commit aa490867b3
No known key found for this signature in database
GPG Key ID: DB511043A31ACAAF
2 changed files with 77 additions and 59 deletions

View File

@ -1,6 +1,9 @@
$Id: Changelog.txt,v 1.242 2019/12/23 23:35:40 nanard Exp $ $Id: Changelog.txt,v 1.242 2019/12/23 23:35:40 nanard Exp $
miniUPnP client Changelog. miniUPnP client Changelog.
2020/09/23:
prevent infinite loop in upnpDiscover()
2020/02/16: 2020/02/16:
Add Haiku support Add Haiku support

View File

@ -10,6 +10,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h>
#if defined (__NetBSD__) #if defined (__NetBSD__)
#include <net/if.h> #include <net/if.h>
#endif #endif
@ -841,73 +842,87 @@ ssdpDiscoverDevices(const char * const deviceTypes[],
/* Waiting for SSDP REPLY packet to M-SEARCH /* Waiting for SSDP REPLY packet to M-SEARCH
* if searchalltypes is set, enter the loop only * if searchalltypes is set, enter the loop only
* when the last deviceType is reached */ * when the last deviceType is reached */
if((sentok && !searchalltypes) || !deviceTypes[deviceIndex + 1]) do { if((sentok && !searchalltypes) || !deviceTypes[deviceIndex + 1]) {
n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id); struct timeval start, current;
if (n < 0) { if (gettimeofday(&start, NULL) < 0) {
/* error */ start.tv_sec = 0;
if(error) start.tv_usec = 0;
*error = MINISSDPC_SOCKET_ERROR; }
goto error; do {
} else if (n == 0) { n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id);
/* no data or Time Out */ if (n < 0) {
#ifdef DEBUG /* error */
printf("NODATA or TIMEOUT\n");
#endif /* DEBUG */
if (devlist && !searchalltypes) {
/* found some devices, stop now*/
if(error) if(error)
*error = MINISSDPC_SUCCESS; *error = MINISSDPC_SOCKET_ERROR;
goto error; goto error;
} } else if (n == 0) {
} else { /* no data or Time Out */
const char * descURL=NULL;
int urlsize=0;
const char * st=NULL;
int stsize=0;
const char * usn=NULL;
int usnsize=0;
parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize, &usn, &usnsize);
if(st&&descURL) {
#ifdef DEBUG #ifdef DEBUG
printf("M-SEARCH Reply:\n ST: %.*s\n USN: %.*s\n Location: %.*s\n", printf("NODATA or TIMEOUT\n");
stsize, st, usnsize, (usn?usn:""), urlsize, descURL);
#endif /* DEBUG */ #endif /* DEBUG */
for(tmp=devlist; tmp; tmp = tmp->pNext) { if (devlist && !searchalltypes) {
if(strncmp(tmp->descURL, descURL, urlsize) == 0 && /* found some devices, stop now*/
tmp->descURL[urlsize] == '\0' &&
strncmp(tmp->st, st, stsize) == 0 &&
tmp->st[stsize] == '\0' &&
(usnsize == 0 || strncmp(tmp->usn, usn, usnsize) == 0) &&
tmp->usn[usnsize] == '\0')
break;
}
/* at the exit of the loop above, tmp is null if
* no duplicate device was found */
if(tmp)
continue;
tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize+3);
if(!tmp) {
/* memory allocation error */
if(error) if(error)
*error = MINISSDPC_MEMORY_ERROR; *error = MINISSDPC_SUCCESS;
goto error; goto error;
} }
tmp->pNext = devlist; } else {
tmp->descURL = tmp->buffer; const char * descURL=NULL;
tmp->st = tmp->buffer + 1 + urlsize; int urlsize=0;
tmp->usn = tmp->st + 1 + stsize; const char * st=NULL;
memcpy(tmp->buffer, descURL, urlsize); int stsize=0;
tmp->buffer[urlsize] = '\0'; const char * usn=NULL;
memcpy(tmp->st, st, stsize); int usnsize=0;
tmp->buffer[urlsize+1+stsize] = '\0'; parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize, &usn, &usnsize);
if(usn != NULL) if(st&&descURL) {
memcpy(tmp->usn, usn, usnsize); #ifdef DEBUG
tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0'; printf("M-SEARCH Reply:\n ST: %.*s\n USN: %.*s\n Location: %.*s\n",
tmp->scope_id = scope_id; stsize, st, usnsize, (usn?usn:""), urlsize, descURL);
devlist = tmp; #endif /* DEBUG */
for(tmp=devlist; tmp; tmp = tmp->pNext) {
if(strncmp(tmp->descURL, descURL, urlsize) == 0 &&
tmp->descURL[urlsize] == '\0' &&
strncmp(tmp->st, st, stsize) == 0 &&
tmp->st[stsize] == '\0' &&
(usnsize == 0 || strncmp(tmp->usn, usn, usnsize) == 0) &&
tmp->usn[usnsize] == '\0')
break;
}
/* at the exit of the loop above, tmp is null if
* no duplicate device was found */
if(tmp)
continue;
tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize+3);
if(!tmp) {
/* memory allocation error */
if(error)
*error = MINISSDPC_MEMORY_ERROR;
goto error;
}
tmp->pNext = devlist;
tmp->descURL = tmp->buffer;
tmp->st = tmp->buffer + 1 + urlsize;
tmp->usn = tmp->st + 1 + stsize;
memcpy(tmp->buffer, descURL, urlsize);
tmp->buffer[urlsize] = '\0';
memcpy(tmp->st, st, stsize);
tmp->buffer[urlsize+1+stsize] = '\0';
if(usn != NULL)
memcpy(tmp->usn, usn, usnsize);
tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0';
tmp->scope_id = scope_id;
devlist = tmp;
}
if (gettimeofday(&current, NULL) >= 0) {
/* exit the loop if delay is reached */
long interval = (current.tv_sec - start.tv_sec) * 1000;
interval += (current.tv_usec - start.tv_usec) / 1000;
if (interval > (long)delay)
break;
}
} }
} } while(n > 0);
} while(n > 0); }
if(ipv6) { if(ipv6) {
/* switch linklocal flag */ /* switch linklocal flag */
if(linklocal) { if(linklocal) {