25241371 problem in LIBRARY/CURL
authorYiteng Zhang <yiteng.zhang@oracle.com>
Tue, 10 Jan 2017 17:35:21 -0800
changeset 7552 17fdfad41903
parent 7551 d7da0f26b875
child 7553 9bd80d515ff3
25241371 problem in LIBRARY/CURL 25241378 problem in LIBRARY/CURL 25241832 problem in LIBRARY/CURL 25241839 problem in LIBRARY/CURL 25241853 problem in LIBRARY/CURL 25241867 problem in LIBRARY/CURL 25241881 problem in LIBRARY/CURL 25241889 problem in LIBRARY/CURL 25241894 problem in LIBRARY/CURL 25241900 problem in LIBRARY/CURL 25306385 problem in LIBRARY/CURL
components/curl/patches/013-CVE-2016-8615.patch
components/curl/patches/014-CVE-2016-8616.patch
components/curl/patches/015-CVE-2016-8617.patch
components/curl/patches/016-CVE-2016-8618.patch
components/curl/patches/017-CVE-2016-8619.patch
components/curl/patches/018-CVE-2016-8620.patch
components/curl/patches/019-CVE-2016-8621.patch
components/curl/patches/020-CVE-2016-8622.patch
components/curl/patches/021-CVE-2016-8623.patch
components/curl/patches/022-CVE-2016-8624.patch
components/curl/patches/023-CVE-2016-9586.patch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/curl/patches/013-CVE-2016-8615.patch	Tue Jan 10 17:35:21 2017 -0800
@@ -0,0 +1,73 @@
+From 1620f552a277ed5b23a48b9c27dbf07663cac068 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Tue, 27 Sep 2016 17:36:19 +0200
+Subject: [PATCH] cookie: replace use of fgets() with custom version
+
+... that will ignore lines that are too long to fit in the buffer.
+
+CVE-2016-8615
+
+Bug: https://curl.haxx.se/docs/adv_20161102A.html
+Reported-by: Cure53
+---
+ lib/cookie.c | 31 ++++++++++++++++++++++++++++++-
+ 1 file changed, 30 insertions(+), 1 deletion(-)
+
+--- lib/cookie.c
++++ lib/cookie.c
+@@ -901,10 +901,39 @@ Curl_cookie_add(struct Curl_easy *data,
+   }
+ 
+   return co;
+ }
+ 
++/*
++ * get_line() makes sure to only return complete whole lines that fit in 'len'
++ * bytes and end with a newline.
++ */
++static char *get_line(char *buf, int len, FILE *input)
++{
++  bool partial = FALSE;
++  while(1) {
++    char *b = fgets(buf, len, input);
++    if(b) {
++      size_t rlen = strlen(b);
++      if(rlen && (b[rlen-1] == '\n')) {
++        if(partial) {
++          partial = FALSE;
++          continue;
++        }
++        return b;
++      }
++      else
++        /* read a partial, discard the next piece that ends with newline */
++        partial = TRUE;
++    }
++    else
++      break;
++  }
++  return NULL;
++}
++
++
+ /*****************************************************************************
+  *
+  * Curl_cookie_init()
+  *
+  * Inits a cookie struct to read data from a local file. This is always
+@@ -957,11 +986,11 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
+     bool headerline;
+ 
+     line = malloc(MAX_COOKIE_LINE);
+     if(!line)
+       goto fail;
+-    while(fgets(line, MAX_COOKIE_LINE, fp)) {
++    while(get_line(line, MAX_COOKIE_LINE, fp)) {
+       if(checkprefix("Set-Cookie:", line)) {
+         /* This is a cookie line, get it! */
+         lineptr=&line[11];
+         headerline=TRUE;
+       }
+-- 
+2.9.3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/curl/patches/014-CVE-2016-8616.patch	Tue Jan 10 17:35:21 2017 -0800
@@ -0,0 +1,60 @@
+From cef510beb222ab5750afcac2c74fcbcdc31ada64 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Tue, 27 Sep 2016 18:01:53 +0200
+Subject: [PATCH] connectionexists: use case sensitive user/password
+ comparisons
+
+CVE-2016-8616
+
+Bug: https://curl.haxx.se/docs/adv_20161102B.html
+Reported-by: Cure53
+---
+ lib/url.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+--- lib/url.c
++++ lib/url.c
+@@ -3401,12 +3401,12 @@ ConnectionExists(struct Curl_easy *data,
+       }
+ 
+       if(!(needle->handler->flags & PROTOPT_CREDSPERREQUEST)) {
+         /* This protocol requires credentials per connection,
+            so verify that we're using the same name and password as well */
+-        if(!strequal(needle->user, check->user) ||
+-           !strequal(needle->passwd, check->passwd)) {
++        if(strcmp(needle->user, check->user) ||
++           strcmp(needle->passwd, check->passwd)) {
+           /* one of them was different */
+           continue;
+         }
+       }
+ 
+@@ -3462,12 +3462,12 @@ ConnectionExists(struct Curl_easy *data,
+            already authenticating with the right credentials. If not, keep
+            looking so that we can reuse NTLM connections if
+            possible. (Especially we must not reuse the same connection if
+            partway through a handshake!) */
+         if(wantNTLMhttp) {
+-          if(!strequal(needle->user, check->user) ||
+-             !strequal(needle->passwd, check->passwd))
++          if(strcmp(needle->user, check->user) ||
++             strcmp(needle->passwd, check->passwd))
+             continue;
+         }
+         else if(check->ntlm.state != NTLMSTATE_NONE) {
+           /* Connection is using NTLM auth but we don't want NTLM */
+           continue;
+@@ -3477,8 +3477,8 @@ ConnectionExists(struct SessionHandle *data,
+         if(wantProxyNTLMhttp) {
+-          if(!strequal(needle->proxyuser, check->proxyuser) ||
+-             !strequal(needle->proxypasswd, check->proxypasswd))
++          if(strcmp(needle->proxyuser, check->proxyuser) ||
++             strcmp(needle->proxypasswd, check->proxypasswd))
+             continue;
+         }
+         else if(check->proxyntlm.state != NTLMSTATE_NONE) {
+           /* Proxy connection is using NTLM auth but we don't want NTLM */
+           continue;
+-- 
+2.9.3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/curl/patches/015-CVE-2016-8617.patch	Tue Jan 10 17:35:21 2017 -0800
@@ -0,0 +1,34 @@
+From 3599341dd611303ee9544839d30f603f606d1082 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Wed, 28 Sep 2016 00:05:12 +0200
+Subject: [PATCH] base64: check for integer overflow on large input
+
+CVE-2016-8617
+
+Bug: https://curl.haxx.se/docs/adv_20161102C.html
+Reported-by: Cure53
+---
+ lib/base64.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- lib/base64.c
++++ lib/base64.c
+@@ -188,10 +188,15 @@ static CURLcode base64_encode(const char *table64,
+   *outlen = 0;
+ 
+   if(0 == insize)
+     insize = strlen(indata);
+ 
++#if SIZEOF_SIZE_T == 4
++  if(insize > UINT_MAX/4)
++    return CURLE_OUT_OF_MEMORY;
++#endif
++
+   base64data = output = malloc(insize*4/3+4);
+   if(NULL == output)
+     return CURLE_OUT_OF_MEMORY;
+ 
+   /*
+-- 
+2.9.3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/curl/patches/016-CVE-2016-8618.patch	Tue Jan 10 17:35:21 2017 -0800
@@ -0,0 +1,48 @@
+From 31106a073882656a2a5ab56c4ce2847e9a334c3c Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Wed, 28 Sep 2016 10:15:34 +0200
+Subject: [PATCH] aprintf: detect wrap-around when growing allocation
+
+On 32bit systems we could otherwise wrap around after 2GB and allocate 0
+bytes and crash.
+
+CVE-2016-8618
+
+Bug: https://curl.haxx.se/docs/adv_20161102D.html
+Reported-by: Cure53
+---
+ lib/mprintf.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- lib/mprintf.c
++++ lib/mprintf.c
+@@ -1034,20 +1034,23 @@ static int alloc_addbyter(int output, FILE *data)
+     }
+     infop->alloc = 32;
+     infop->len =0;
+   }
+   else if(infop->len+1 >= infop->alloc) {
+-    char *newptr;
++    char *newptr = NULL;
++    size_t newsize = infop->alloc*2;
+ 
+-    newptr = realloc(infop->buffer, infop->alloc*2);
++    /* detect wrap-around or other overflow problems */
++    if(newsize > infop->alloc)
++      newptr = realloc(infop->buffer, newsize);
+ 
+     if(!newptr) {
+       infop->fail = 1;
+       return -1; /* fail */
+     }
+     infop->buffer = newptr;
+-    infop->alloc *= 2;
++    infop->alloc = newsize;
+   }
+ 
+   infop->buffer[ infop->len ] = outc;
+ 
+   infop->len++;
+-- 
+2.9.3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/curl/patches/017-CVE-2016-8619.patch	Tue Jan 10 17:35:21 2017 -0800
@@ -0,0 +1,48 @@
+From 91239f7040b1f026d4d15765e7e3f58e92e93761 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Wed, 28 Sep 2016 12:56:02 +0200
+Subject: [PATCH] krb5: avoid realloc(0)
+
+If the requested size is zero, bail out with error instead of doing a
+realloc() that would cause a double-free: realloc(0) acts as a free()
+and then there's a second free in the cleanup path.
+
+CVE-2016-8619
+
+Bug: https://curl.haxx.se/docs/adv_20161102E.html
+Reported-by: Cure53
+---
+ lib/security.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- lib/security.c
++++ lib/security.c
+@@ -190,19 +190,22 @@ socket_write(struct connectdata *conn, curl_socket_t fd, const void *to,
+ static CURLcode read_data(struct connectdata *conn,
+                           curl_socket_t fd,
+                           struct krb5buffer *buf)
+ {
+   int len;
+-  void* tmp;
++  void *tmp = NULL;
+   CURLcode result;
+ 
+   result = socket_read(fd, &len, sizeof(len));
+   if(result)
+     return result;
+ 
+-  len = ntohl(len);
+-  tmp = realloc(buf->data, len);
++  if(len) {
++    /* only realloc if there was a length */
++    len = ntohl(len);
++    tmp = realloc(buf->data, len);
++  }
+   if(tmp == NULL)
+     return CURLE_OUT_OF_MEMORY;
+ 
+   buf->data = tmp;
+   result = socket_read(fd, buf->data, len);
+-- 
+2.9.3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/curl/patches/018-CVE-2016-8620.patch	Tue Jan 10 17:35:21 2017 -0800
@@ -0,0 +1,200 @@
+From 52f3e1d1092c81a4f574c9fc6cb3818b88434c8d Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Mon, 3 Oct 2016 17:27:16 +0200
+Subject: [PATCH 1/3] range: prevent negative end number in a glob range
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+CVE-2016-8620
+
+Bug: https://curl.haxx.se/docs/adv_20161102F.html
+Reported-by: Luật Nguyễn
+---
+ src/tool_urlglob.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+--- src/tool_urlglob.c
++++ src/tool_urlglob.c
+@@ -255,10 +255,16 @@ static CURLcode glob_range(URLGlob *glob, char **patternp,
+     else {
+       if(*endp != '-')
+         endp = NULL;
+       else {
+         pattern = endp+1;
++        while(*pattern && ISBLANK(*pattern))
++          pattern++;
++        if(!ISDIGIT(*pattern)) {
++          endp = NULL;
++          goto fail;
++        }
+         errno = 0;
+         max_n = strtoul(pattern, &endp, 10);
+         if(errno || (*endp == ':')) {
+           pattern = endp+1;
+           errno = 0;
+@@ -275,11 +281,12 @@ static CURLcode glob_range(URLGlob *glob, char **patternp,
+         else
+           endp = NULL;
+       }
+     }
+ 
++    fail:
+     *posp += (pattern - *patternp);
+ 
+     if(!endp || (min_n > max_n) || (step_n > (max_n - min_n)) ||
+        (step_n <= 0) )
+       /* the pattern is not well-formed */
+       return GLOBERROR("bad range", *posp, CURLE_URL_MALFORMAT);
+-- 
+2.9.3
+
+
+From e97ebe97c2b53d3617c1f4082a2aaa4f1b593ef9 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Mon, 3 Oct 2016 18:23:22 +0200
+Subject: [PATCH 2/3] glob_next_url: make sure to stay within the given output
+ buffer
+
+---
+ src/tool_urlglob.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+--- src/tool_urlglob.c
++++ src/tool_urlglob.c
+@@ -429,10 +429,11 @@ CURLcode glob_url(URLGlob** glob, char* url, unsigned long *urlnum,
+   *glob = NULL;
+ 
+   glob_buffer = malloc(strlen(url) + 1);
+   if(!glob_buffer)
+     return CURLE_OUT_OF_MEMORY;
++  glob_buffer[0]=0;
+ 
+   glob_expand = calloc(1, sizeof(URLGlob));
+   if(!glob_expand) {
+     Curl_safefree(glob_buffer);
+     return CURLE_OUT_OF_MEMORY;
+@@ -546,33 +547,37 @@ CURLcode glob_next_url(char **globbed, URLGlob *glob)
+   for(i = 0; i < glob->size; ++i) {
+     pat = &glob->pattern[i];
+     switch(pat->type) {
+     case UPTSet:
+       if(pat->content.Set.elements) {
+-        len = strlen(pat->content.Set.elements[pat->content.Set.ptr_s]);
+         snprintf(buf, buflen, "%s",
+                  pat->content.Set.elements[pat->content.Set.ptr_s]);
++        len = strlen(buf);
+         buf += len;
+         buflen -= len;
+       }
+       break;
+     case UPTCharRange:
+-      *buf++ = pat->content.CharRange.ptr_c;
++      if(buflen) {
++        *buf++ = pat->content.CharRange.ptr_c;
++        *buf = '\0';
++        buflen--;
++      }
+       break;
+     case UPTNumRange:
+-      len = snprintf(buf, buflen, "%0*ld",
+-                     pat->content.NumRange.padlength,
+-                     pat->content.NumRange.ptr_n);
++      snprintf(buf, buflen, "%0*ld",
++               pat->content.NumRange.padlength,
++               pat->content.NumRange.ptr_n);
++      len = strlen(buf);
+       buf += len;
+       buflen -= len;
+       break;
+     default:
+       printf("internal error: invalid pattern type (%d)\n", (int)pat->type);
+       return CURLE_FAILED_INIT;
+     }
+   }
+-  *buf = '\0';
+ 
+   *globbed = strdup(glob->glob_buffer);
+   if(!*globbed)
+     return CURLE_OUT_OF_MEMORY;
+ 
+-- 
+2.9.3
+
+
+From 9ce377051290c83176f235b526b87904cad6b388 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Tue, 4 Oct 2016 17:25:09 +0200
+Subject: [PATCH 3/3] range: reject char globs with missing end like '[L-]'
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+... which previously would lead to out of boundary reads.
+
+Reported-by: Luật Nguyễn
+---
+ src/tool_urlglob.c | 34 +++++++++++++++++++---------------
+ 1 file changed, 19 insertions(+), 15 deletions(-)
+
+--- src/tool_urlglob.c
++++ src/tool_urlglob.c
+@@ -186,36 +186,40 @@ static CURLcode glob_range(URLGlob *glob, char **patternp,
+ 
+   if(ISALPHA(*pattern)) {
+     /* character range detected */
+     char min_c;
+     char max_c;
++    char end_c;
+     int step=1;
+ 
+     pat->type = UPTCharRange;
+ 
+-    rc = sscanf(pattern, "%c-%c", &min_c, &max_c);
++    rc = sscanf(pattern, "%c-%c%c", &min_c, &max_c, &end_c);
+ 
+-    if((rc == 2) && (pattern[3] == ':')) {
+-      char *endp;
+-      unsigned long lstep;
+-      errno = 0;
+-      lstep = strtoul(&pattern[4], &endp, 10);
+-      if(errno || (*endp != ']'))
+-        step = -1;
+-      else {
+-        pattern = endp+1;
+-        step = (int)lstep;
+-        if(step > (max_c - min_c))
++    if(rc == 3) {
++      if(end_c == ':') {
++        char *endp;
++        unsigned long lstep;
++        errno = 0;
++        lstep = strtoul(&pattern[4], &endp, 10);
++        if(errno || (*endp != ']'))
+           step = -1;
++        else {
++          pattern = endp+1;
++          step = (int)lstep;
++          if(step > (max_c - min_c))
++            step = -1;
++        }
+       }
++      else if(end_c != ']')
++        /* then this is wrong */
++        rc = 0;
+     }
+-    else
+-      pattern += 4;
+ 
+     *posp += (pattern - *patternp);
+ 
+-    if((rc != 2) || (min_c >= max_c) || ((max_c - min_c) > ('z' - 'a')) ||
++    if((rc != 3) || (min_c >= max_c) || ((max_c - min_c) > ('z' - 'a')) ||
+        (step <= 0) )
+       /* the pattern is not well-formed */
+       return GLOBERROR("bad range", *posp, CURLE_URL_MALFORMAT);
+ 
+     /* if there was a ":[num]" thing, use that as step or else use 1 */
+-- 
+2.9.3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/curl/patches/019-CVE-2016-8621.patch	Tue Jan 10 17:35:21 2017 -0800
@@ -0,0 +1,115 @@
+From 8a6d9ded5f02f0294ae63a007e26087316c1998e Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Tue, 4 Oct 2016 16:59:38 +0200
+Subject: [PATCH] parsedate: handle cut off numbers better
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+... and don't read outside of the given buffer!
+
+CVE-2016-8621
+
+bug: https://curl.haxx.se/docs/adv_20161102G.html
+Reported-by: Luật Nguyễn
+---
+ lib/parsedate.c        | 12 +++++++-----
+ tests/data/test517     |  6 ++++++
+ tests/libtest/lib517.c |  8 +++++++-
+ 3 files changed, 20 insertions(+), 6 deletions(-)
+
+--- lib/parsedate.c
++++ lib/parsedate.c
+@@ -3,11 +3,11 @@
+  *  Project                     ___| | | |  _ \| |
+  *                             / __| | | | |_) | |
+  *                            | (__| |_| |  _ <| |___
+  *                             \___|\___/|_| \_\_____|
+  *
+- * Copyright (C) 1998 - 2014, Daniel Stenberg, <[email protected]>, et al.
++ * Copyright (C) 1998 - 2016, Daniel Stenberg, <[email protected]>, et al.
+  *
+  * This software is licensed as described in the file COPYING, which
+  * you should have received as part of this distribution. The terms
+  * are also available at https://curl.haxx.se/docs/copyright.html.
+  *
+@@ -384,19 +384,21 @@ static int parsedate(const char *date, time_t *output)
+     }
+     else if(ISDIGIT(*date)) {
+       /* a digit */
+       int val;
+       char *end;
++      int len=0;
+       if((secnum == -1) &&
+-         (3 == sscanf(date, "%02d:%02d:%02d", &hournum, &minnum, &secnum))) {
++         (3 == sscanf(date, "%02d:%02d:%02d%n",
++                      &hournum, &minnum, &secnum, &len))) {
+         /* time stamp! */
+-        date += 8;
++        date += len;
+       }
+       else if((secnum == -1) &&
+-              (2 == sscanf(date, "%02d:%02d", &hournum, &minnum))) {
++              (2 == sscanf(date, "%02d:%02d%n", &hournum, &minnum, &len))) {
+         /* time stamp without seconds */
+-        date += 5;
++        date += len;
+         secnum = 0;
+       }
+       else {
+         long lval;
+         int error;
+--- tests/data/test517
++++ tests/data/test517
+@@ -114,10 +114,16 @@ nothing
+ 79: 20110632 12:34:56 => -1
+ 80: 20110623 56:34:56 => -1
+ 81: 20111323 12:34:56 => -1
+ 82: 20110623 12:34:79 => -1
+ 83: Wed, 31 Dec 2008 23:59:60 GMT => 1230768000
++84: 20110623 12:3 => 1308830580
++85: 20110623 1:3 => 1308790980
++86: 20110623 1:30 => 1308792600
++87: 20110623 12:12:3 => 1308831123
++88: 20110623 01:12:3 => 1308791523
++89: 20110623 01:99:30 => -1
+ </stdout>
+ 
+ # This test case previously tested an overflow case ("2094 Nov 6 =>
+ # 2147483647") for 32bit time_t, but since some systems have 64bit time_t and
+ # handles this (returning 3939840000), and some 64bit-time_t systems don't
+--- tests/libtest/lib517.c
++++ tests/libtest/lib517.c
+@@ -3,11 +3,11 @@
+  *  Project                     ___| | | |  _ \| |
+  *                             / __| | | | |_) | |
+  *                            | (__| |_| |  _ <| |___
+  *                             \___|\___/|_| \_\_____|
+  *
+- * Copyright (C) 1998 - 2011, Daniel Stenberg, <[email protected]>, et al.
++ * Copyright (C) 1998 - 2016, Daniel Stenberg, <[email protected]>, et al.
+  *
+  * This software is licensed as described in the file COPYING, which
+  * you should have received as part of this distribution. The terms
+  * are also available at https://curl.haxx.se/docs/copyright.html.
+  *
+@@ -114,10 +114,16 @@ static const char * const dates[]={
+   "20110632 12:34:56",
+   "20110623 56:34:56",
+   "20111323 12:34:56",
+   "20110623 12:34:79",
+   "Wed, 31 Dec 2008 23:59:60 GMT", /* leap second */
++  "20110623 12:3",
++  "20110623 1:3",
++  "20110623 1:30",
++  "20110623 12:12:3",
++  "20110623 01:12:3",
++  "20110623 01:99:30",
+   NULL
+ };
+ 
+ int test(char *URL)
+ {
+-- 
+2.9.3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/curl/patches/020-CVE-2016-8622.patch	Tue Jan 10 17:35:21 2017 -0800
@@ -0,0 +1,120 @@
+From 71da91453899ba20b28ee9712620e323145a0ee5 Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Tue, 4 Oct 2016 18:56:45 +0200
+Subject: [PATCH] unescape: avoid integer overflow
+
+CVE-2016-8622
+
+Bug: https://curl.haxx.se/docs/adv_20161102H.html
+Reported-by: Cure53
+---
+ docs/libcurl/curl_easy_unescape.3 |  7 +++++--
+ lib/dict.c                        | 10 +++++-----
+ lib/escape.c                      | 10 ++++++++--
+ 3 files changed, 18 insertions(+), 9 deletions(-)
+
+--- docs/libcurl/curl_easy_unescape.3
++++ docs/libcurl/curl_easy_unescape.3
+@@ -3,11 +3,11 @@
+ .\" *  Project                     ___| | | |  _ \| |
+ .\" *                             / __| | | | |_) | |
+ .\" *                            | (__| |_| |  _ <| |___
+ .\" *                             \___|\___/|_| \_\_____|
+ .\" *
+-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <[email protected]>, et al.
++.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, <[email protected]>, et al.
+ .\" *
+ .\" * This software is licensed as described in the file COPYING, which
+ .\" * you should have received as part of this distribution. The terms
+ .\" * are also available at https://curl.haxx.se/docs/copyright.html.
+ .\" *
+@@ -38,11 +38,14 @@ their binary versions.
+ If the \fBlength\fP argument is set to 0 (zero), \fIcurl_easy_unescape(3)\fP
+ will use strlen() on the input \fIurl\fP string to find out the size.
+ 
+ If \fBoutlength\fP is non-NULL, the function will write the length of the
+ returned string in the integer it points to. This allows an escaped string
+-containing %00 to still get used properly after unescaping.
++containing %00 to still get used properly after unescaping. Since this is a
++pointer to an \fIint\fP type, it can only return a value up to INT_MAX so no
++longer string can be unescaped if the string length is returned in this
++parameter.
+ 
+ You must \fIcurl_free(3)\fP the returned string when you're done with it.
+ .SH AVAILABILITY
+ Added in 7.15.4 and replaces the old \fIcurl_unescape(3)\fP function.
+ .SH RETURN VALUE
+--- lib/dict.c
++++ lib/dict.c
+@@ -3,11 +3,11 @@
+  *  Project                     ___| | | |  _ \| |
+  *                             / __| | | | |_) | |
+  *                            | (__| |_| |  _ <| |___
+  *                             \___|\___/|_| \_\_____|
+  *
+- * Copyright (C) 1998 - 2015, Daniel Stenberg, <[email protected]>, et al.
++ * Copyright (C) 1998 - 2016, Daniel Stenberg, <[email protected]>, et al.
+  *
+  * This software is licensed as described in the file COPYING, which
+  * you should have received as part of this distribution. The terms
+  * are also available at https://curl.haxx.se/docs/copyright.html.
+  *
+@@ -50,11 +50,11 @@
+ 
+ #include "urldata.h"
+ #include <curl/curl.h>
+ #include "transfer.h"
+ #include "sendf.h"
+-
++#include "escape.h"
+ #include "progress.h"
+ #include "strequal.h"
+ #include "dict.h"
+ #include "rawstr.h"
+ #include "curl_memory.h"
+@@ -94,16 +94,16 @@ const struct Curl_handler Curl_handler_dict = {
+ static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
+ {
+   char *newp;
+   char *dictp;
+   char *ptr;
+-  int len;
++  size_t len;
+   char ch;
+   int olen=0;
+ 
+-  newp = curl_easy_unescape(data, inputbuff, 0, &len);
+-  if(!newp)
++  CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len, FALSE);
++  if(!newp || result)
+     return NULL;
+ 
+   dictp = malloc(((size_t)len)*2 + 1); /* add one for terminating zero */
+   if(dictp) {
+     /* According to RFC2229 section 2.2, these letters need to be escaped with
+--- lib/escape.c
++++ lib/escape.c
+@@ -222,12 +222,18 @@ char *curl_easy_unescape(struct Curl_easy *data, const char *string,
+     size_t outputlen;
+     CURLcode res = Curl_urldecode(data, string, inputlen, &str, &outputlen,
+                                   FALSE);
+     if(res)
+       return NULL;
+-    if(olen)
+-      *olen = curlx_uztosi(outputlen);
++
++    if(olen) {
++      if(outputlen <= (size_t) INT_MAX)
++        *olen = curlx_uztosi(outputlen);
++      else
++        /* too large to return in an int, fail! */
++        Curl_safefree(str);
++    }
+   }
+   return str;
+ }
+ 
+ /* For operating systems/environments that use different malloc/free
+-- 
+2.9.3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/curl/patches/021-CVE-2016-8623.patch	Tue Jan 10 17:35:21 2017 -0800
@@ -0,0 +1,201 @@
+From d9d57fe0da6f25d05570fd583520ecd321ed9c3f Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Tue, 4 Oct 2016 23:26:13 +0200
+Subject: [PATCH] cookies: getlist() now holds deep copies of all cookies
+
+Previously it only held references to them, which was reckless as the
+thread lock was released so the cookies could get modified by other
+handles that share the same cookie jar over the share interface.
+
+CVE-2016-8623
+
+Bug: https://curl.haxx.se/docs/adv_20161102I.html
+Reported-by: Cure53
+---
+ lib/cookie.c | 61 +++++++++++++++++++++++++++++++++++++++---------------------
+ lib/cookie.h |  4 ++--
+ lib/http.c   |  2 +-
+ 3 files changed, 43 insertions(+), 24 deletions(-)
+
+--- lib/cookie.c
++++ lib/cookie.c
+@@ -1022,10 +1022,44 @@ static int cookie_sort(const void *p1, const void *p2)
+ 
+   /* sorry, can't be more deterministic */
+   return 0;
+ }
+ 
++#define CLONE(field)                     \
++  do {                                   \
++    if(src->field) {                     \
++      dup->field = strdup(src->field);   \
++      if(!dup->field)                    \
++        goto fail;                       \
++    }                                    \
++  } while(0)
++
++static struct Cookie *dup_cookie(struct Cookie *src)
++{
++  struct Cookie *dup = calloc(sizeof(struct Cookie), 1);
++  if(dup) {
++    CLONE(expirestr);
++    CLONE(domain);
++    CLONE(path);
++    CLONE(spath);
++    CLONE(name);
++    CLONE(value);
++    CLONE(maxage);
++    CLONE(version);
++    dup->expires = src->expires;
++    dup->tailmatch = src->tailmatch;
++    dup->secure = src->secure;
++    dup->livecookie = src->livecookie;
++    dup->httponly = src->httponly;
++  }
++  return dup;
++
++  fail:
++  freecookie(dup);
++  return NULL;
++}
++
+ /*****************************************************************************
+  *
+  * Curl_cookie_getlist()
+  *
+  * For a given host and path, return a linked list of cookies that the
+@@ -1077,15 +1111,12 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
+         if(!co->spath || pathmatch(co->spath, path) ) {
+ 
+           /* and now, we know this is a match and we should create an
+              entry for the return-linked-list */
+ 
+-          newco = malloc(sizeof(struct Cookie));
++          newco = dup_cookie(co);
+           if(newco) {
+-            /* first, copy the whole source cookie: */
+-            memcpy(newco, co, sizeof(struct Cookie));
+-
+             /* then modify our next */
+             newco->next = mainco;
+ 
+             /* point the main to us */
+             mainco = newco;
+@@ -1093,16 +1124,11 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
+             matches++;
+           }
+           else {
+             fail:
+             /* failure, clear up the allocated chain and return NULL */
+-            while(mainco) {
+-              co = mainco->next;
+-              free(mainco);
+-              mainco = co;
+-            }
+-
++            Curl_cookie_freelist(mainco);
+             return NULL;
+           }
+         }
+       }
+     }
+@@ -1150,11 +1176,11 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
+  *
+  ****************************************************************************/
+ void Curl_cookie_clearall(struct CookieInfo *cookies)
+ {
+   if(cookies) {
+-    Curl_cookie_freelist(cookies->cookies, TRUE);
++    Curl_cookie_freelist(cookies->cookies);
+     cookies->cookies = NULL;
+     cookies->numcookies = 0;
+   }
+ }
+ 
+@@ -1162,25 +1188,18 @@ void Curl_cookie_clearall(struct CookieInfo *cookies)
+  *
+  * Curl_cookie_freelist()
+  *
+  * Free a list of cookies previously returned by Curl_cookie_getlist();
+  *
+- * The 'cookiestoo' argument tells this function whether to just free the
+- * list or actually also free all cookies within the list as well.
+- *
+  ****************************************************************************/
+ 
+-void Curl_cookie_freelist(struct Cookie *co, bool cookiestoo)
++void Curl_cookie_freelist(struct Cookie *co)
+ {
+   struct Cookie *next;
+   while(co) {
+     next = co->next;
+-    if(cookiestoo)
+-      freecookie(co);
+-    else
+-      free(co); /* we only free the struct since the "members" are all just
+-                   pointed out in the main cookie list! */
++    freecookie(co);
+     co = next;
+   }
+ }
+ 
+ 
+@@ -1231,11 +1250,11 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies)
+  ****************************************************************************/
+ void Curl_cookie_cleanup(struct CookieInfo *c)
+ {
+   if(c) {
+     free(c->filename);
+-    Curl_cookie_freelist(c->cookies, TRUE);
++    Curl_cookie_freelist(c->cookies);
+     free(c); /* free the base struct as well */
+   }
+ }
+ 
+ /* get_netscape_format()
+--- lib/cookie.h
++++ lib/cookie.h
+@@ -5,11 +5,11 @@
+  *  Project                     ___| | | |  _ \| |
+  *                             / __| | | | |_) | |
+  *                            | (__| |_| |  _ <| |___
+  *                             \___|\___/|_| \_\_____|
+  *
+- * Copyright (C) 1998 - 2011, Daniel Stenberg, <[email protected]>, et al.
++ * Copyright (C) 1998 - 2016, Daniel Stenberg, <[email protected]>, et al.
+  *
+  * This software is licensed as described in the file COPYING, which
+  * you should have received as part of this distribution. The terms
+  * are also available at https://curl.haxx.se/docs/copyright.html.
+  *
+@@ -80,11 +80,11 @@ struct Cookie *Curl_cookie_add(struct Curl_easy *data,
+                                struct CookieInfo *, bool header, char *lineptr,
+                                const char *domain, const char *path);
+ 
+ struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *,
+                                    const char *, bool);
+-void Curl_cookie_freelist(struct Cookie *cookies, bool cookiestoo);
++void Curl_cookie_freelist(struct Cookie *cookies);
+ void Curl_cookie_clearall(struct CookieInfo *cookies);
+ void Curl_cookie_clearsess(struct CookieInfo *cookies);
+ 
+ #if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
+ #define Curl_cookie_list(x) NULL
+--- lib/http.c
++++ lib/http.c
+@@ -2382,11 +2382,11 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
+             break;
+           count++;
+         }
+         co = co->next; /* next cookie please */
+       }
+-      Curl_cookie_freelist(store, FALSE); /* free the cookie list */
++      Curl_cookie_freelist(store);
+     }
+     if(addcookies && !result) {
+       if(!count)
+         result = Curl_add_bufferf(req_buffer, "Cookie: ");
+       if(!result) {
+-- 
+2.9.3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/curl/patches/022-CVE-2016-8624.patch	Tue Jan 10 17:35:21 2017 -0800
@@ -0,0 +1,65 @@
+From 6604d4df30aec66db6f5bd51ee3c341dd7329fcf Mon Sep 17 00:00:00 2001
+From: Daniel Stenberg <[email protected]>
+Date: Tue, 11 Oct 2016 00:48:35 +0200
+Subject: [PATCH] urlparse: accept '#' as end of host name
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+'http://example.com#@127.0.0.1/x.txt' equals a request to example.com
+for the '/' document with the rest of the URL being a fragment.
+
+CVE-2016-8624
+
+Bug: https://curl.haxx.se/docs/adv_20161102J.html
+Reported-by: Fernando Muñoz
+---
+ lib/url.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- lib/url.c
++++ lib/url.c
+@@ -4162,8 +4162,8 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
+     /* clear path */
+     path[0]=0;
+ 
+     if(2 > sscanf(data->change.url,
+-                   "%15[^\n:]://%[^\n/?]%[^\n]",
++                   "%15[^\n:]://%[^\n/?#]%[^\n]",
+                    protobuf,
+                    conn->host.name, path)) {
+
+@@ -4174,11 +4174,11 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
+ 
+       /*
+        * The URL was badly formatted, let's try the browser-style _without_
+        * protocol specified like 'http://'.
+        */
+-      rc = sscanf(data->change.url, "%[^\n/?]%[^\n]", conn->host.name, path);
++      rc = sscanf(data->change.url, "%[^\n/?#]%[^\n]", conn->host.name, path);
+       if(1 > rc) {
+         /*
+          * We couldn't even get this format.
+          * djgpp 2.04 has a sscanf() bug where 'conn->host.name' is
+          * assigned, but the return value is EOF!
+@@ -4279,14 +4279,14 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
+     strcpy(path, "/");
+     rebuild_url = TRUE;
+   }
+ 
+   /* If the URL is malformatted (missing a '/' after hostname before path) we
+-   * insert a slash here. The only letter except '/' we accept to start a path
+-   * is '?'.
++   * insert a slash here. The only letters except '/' that can start a path is
++   * '?' and '#' - as controlled by the two sscanf() patterns above.
+    */
+-  if(path[0] == '?') {
++  if(path[0] != '/') {
+     /* We need this function to deal with overlapping memory areas. We know
+        that the memory area 'path' points to is 'urllen' bytes big and that
+        is bigger than the path. Use +1 to move the zero byte too. */
+     memmove(&path[1], path, strlen(path)+1);
+     path[0] = '/';
+-- 
+2.9.3
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/curl/patches/023-CVE-2016-9586.patch	Tue Jan 10 17:35:21 2017 -0800
@@ -0,0 +1,69 @@
+commit 3ab3c16db6a5674f53cf23d56512a405fde0b2c9
+Author: Daniel Stenberg <[email protected]>
+Date:   Tue Nov 8 15:32:37 2016 +0100
+
+    printf: fix floating point buffer overflow issues
+    
+    ... and add a bunch of floating point printf tests
+
+This patch is modified to adapt to curl 7.45.0 in Solaris.
+--- lib/mprintf.c
++++ lib/mprintf.c
+@@ -90,11 +90,12 @@
+ #else
+ #  define mp_intmax_t long
+ #  define mp_uintmax_t unsigned long
+ #endif
+ 
+-#define BUFFSIZE 256 /* buffer for long-to-str and float-to-str calcs */
++#define BUFFSIZE 326 /* buffer for long-to-str and float-to-str calcs, should
++                        fit negative DBL_MAX (317 letters) */
+ #define MAX_PARAMETERS 128 /* lame static limit */
+ 
+ #ifdef __AMIGA__
+ # undef FORMAT_INT
+ #endif
+@@ -914,16 +915,29 @@ static int dprintf_formatf(
+           *fptr++ = '#';
+ 
+         *fptr = 0;
+ 
+         if(width >= 0) {
++          if(width >= (long)sizeof(work))
++            width = sizeof(work)-1;
+           /* RECURSIVE USAGE */
+           len = curl_msnprintf(fptr, left, "%ld", width);
+           fptr += len;
+           left -= len;
+         }
+         if(prec >= 0) {
++          /* for each digit in the integer part, we can have one less
++             precision */
++          size_t maxprec = sizeof(work) - 2;
++          double val = p->data.dnum;
++          while(val >= 10.0) {
++            val /= 10;
++            maxprec--;
++          }
++
++          if(prec > (long)maxprec)
++            prec = maxprec-1;
+           /* RECURSIVE USAGE */
+           len = curl_msnprintf(fptr, left, ".%ld", prec);
+           fptr += len;
+         }
+         if(p->flags & FLAGS_LONG)
+@@ -939,11 +953,13 @@ static int dprintf_formatf(
+         *fptr = 0; /* and a final zero termination */
+ 
+         /* NOTE NOTE NOTE!! Not all sprintf implementations return number of
+            output characters */
+         (sprintf)(work, formatbuf, p->data.dnum);
+-
++#ifdef CURLDEBUG
++        assert(strlen(work) <= sizeof(work));
++#endif
+         for(fptr=work; *fptr; fptr++)
+           OUTCHAR(*fptr);
+       }
+       break;