diff -u miniupnpc-1.6/debian/changelog miniupnpc-1.6/debian/changelog --- miniupnpc-1.6/debian/changelog +++ miniupnpc-1.6/debian/changelog @@ -1,3 +1,16 @@ +miniupnpc (1.6-3ubuntu2.14.04.3) trusty-security; urgency=medium + + * SECURITY UPDATE: integer signedness error + - miniwget.c: fix comparisons. + - https://github.com/miniupnp/miniupnp/commit/f0f1f4b22d6a98536377a1bb07e7c20e4703d229 + - CVE-2017-8798 + * SECURITY UPDATE: buffer overflow in simpleUPnPcommand2 + - miniupnpc.c: perform better checking while writing buffer. + - https://github.com/miniupnp/miniupnp/commit/fb02299fffd62fe8584f26aa69547266488e002e + - No CVE number + + -- Marc Deslauriers Fri, 19 May 2017 11:38:20 -0400 + miniupnpc (1.6-3ubuntu2.14.04.2) trusty-security; urgency=medium * SECURITY UPDATE: buffer overflow in XML parser (LP: #1506017) diff -u miniupnpc-1.6/miniwget.c miniupnpc-1.6/miniwget.c --- miniupnpc-1.6/miniwget.c +++ miniupnpc-1.6/miniwget.c @@ -67,13 +67,13 @@ unsigned int bytestocopy = 0; /* buffers : */ char * header_buf; - int header_buf_len = 2048; - int header_buf_used = 0; + unsigned int header_buf_len = 2048; + unsigned int header_buf_used = 0; char * content_buf; - int content_buf_len = 2048; - int content_buf_used = 0; + unsigned int content_buf_len = 2048; + unsigned int content_buf_used = 0; char chunksize_buf[32]; - int chunksize_buf_index; + unsigned int chunksize_buf_index; header_buf = malloc(header_buf_len); content_buf = malloc(content_buf_len); @@ -97,14 +97,14 @@ /* search for CR LF CR LF (end of headers) * recognize also LF LF */ i = 0; - while(i < (header_buf_used-1) && (endofheaders == 0)) { + while(i < ((int)header_buf_used-1) && (endofheaders == 0)) { if(header_buf[i] == '\r') { i++; if(header_buf[i] == '\n') { i++; - if(i < header_buf_used && header_buf[i] == '\r') { + if(i < (int)header_buf_used && header_buf[i] == '\r') { i++; - if(i < header_buf_used && header_buf[i] == '\n') { + if(i < (int)header_buf_used && header_buf[i] == '\n') { endofheaders = i+1; } } @@ -194,7 +194,7 @@ i++; /* discarding chunk-extension */ if(i= '0' && chunksize_buf[j] <= '9') @@ -221,13 +221,13 @@ goto end_of_stream; } } - bytestocopy = ((int)chunksize < n - i)?chunksize:(n - i); - if((int)(content_buf_used + bytestocopy) > content_buf_len) + bytestocopy = (chunksize < (unsigned int)(n - i))?chunksize:(unsigned int)(n - i); + if((content_buf_used + bytestocopy) > content_buf_len) { - if(content_length >= content_buf_used + (int)bytestocopy) { + if(content_length >= 0 && (unsigned int)content_length >= (content_buf_used + bytestocopy)) { content_buf_len = content_length; } else { - content_buf_len = content_buf_used + (int)bytestocopy; + content_buf_len = content_buf_used + bytestocopy; } content_buf = (char *)realloc((void *)content_buf, content_buf_len); @@ -242,13 +242,14 @@ { /* not chunked */ if(content_length > 0 - && (content_buf_used + n) > content_length) { + && (content_buf_used + n) > (unsigned int)content_length) { /* skipping additional bytes */ n = content_length - content_buf_used; } if(content_buf_used + n > content_buf_len) { - if(content_length >= content_buf_used + n) { + if(content_length >= 0 + && (unsigned int)content_length >= (content_buf_used + n)) { content_buf_len = content_length; } else { content_buf_len = content_buf_used + n; @@ -261,7 +262,7 @@ } } /* use the Content-Length header value if available */ - if(content_length > 0 && content_buf_used >= content_length) + if(content_length > 0 && content_buf_used >= (unsigned int)content_length) { #ifdef DEBUG printf("End of HTTP content\n"); only in patch2: unchanged: --- miniupnpc-1.6.orig/miniupnpc.c +++ miniupnpc-1.6/miniupnpc.c @@ -139,6 +139,7 @@ char * p; const char * pe, * pv; int soapbodylen; + const char * const pend = soapbody + sizeof(soapbody); soapbodylen = snprintf(soapbody, sizeof(soapbody), "\r\n" "<" SOAPPREFIX ":Envelope " @@ -150,39 +151,54 @@ p = soapbody + soapbodylen; while(args->elt) { - /* check that we are never overflowing the string... */ - if(soapbody + sizeof(soapbody) <= p + 100) - { - /* we keep a margin of at least 100 bytes */ + if((p+1) > pend) /* check for space to write next byte */ return NULL; - } *(p++) = '<'; + pe = args->elt; - while(*pe) + while(p < pend && *pe) *(p++) = *(pe++); + + if((p+1) > pend) /* check for space to write next byte */ + return NULL; *(p++) = '>'; + if((pv = args->val)) { - while(*pv) + while(p < pend && *pv) *(p++) = *(pv++); } + + if((p+2) > pend) /* check for space to write next 2 bytes */ + return NULL; *(p++) = '<'; *(p++) = '/'; + pe = args->elt; - while(*pe) + while(p < pend && *pe) *(p++) = *(pe++); + + if((p+1) > pend) /* check for space to write next byte */ + return NULL; *(p++) = '>'; + args++; } + if((p+4) > pend) /* check for space to write next 4 bytes */ + return NULL; *(p++) = '<'; *(p++) = '/'; *(p++) = SERVICEPREFIX2; *(p++) = ':'; + pe = action; - while(*pe) + while(p < pend && *pe) *(p++) = *(pe++); + strncpy(p, ">\r\n", - soapbody + sizeof(soapbody) - p); + pend - p); + if(soapbody[sizeof(soapbody)-1]) /* strncpy pads buffer with 0s, so if it doesn't end in 0, could not fit full string */ + return NULL; } if(!parseURL(url, hostname, &port, &path)) return NULL; if(s<0)