From ba3dc3d210189d8b88c35c3b6850f54f8041f3fa Mon Sep 17 00:00:00 2001 From: Sergey Lukin Date: Fri, 9 Dec 2016 08:23:32 +0000 Subject: main/curl: security upgrade - fixes #6437 CVE-2016-8615, CVE-2016-8616, CVE-2016-8617, CVE-2016-8618, CVE-2016-8619, CVE-2016-8620, CVE-2016-8621 CVE-2016-8622, CVE-2016-8623, CVE-2016-8624 --- main/curl/APKBUILD | 49 ++++++++- main/curl/CVE-2016-8615.patch | 75 +++++++++++++ main/curl/CVE-2016-8616.patch | 66 ++++++++++++ main/curl/CVE-2016-8617.patch | 36 +++++++ main/curl/CVE-2016-8618.patch | 50 +++++++++ main/curl/CVE-2016-8619.patch | 50 +++++++++ main/curl/CVE-2016-8620.patch | 205 +++++++++++++++++++++++++++++++++++ main/curl/CVE-2016-8621.patch | 121 +++++++++++++++++++++ main/curl/CVE-2016-8622.patch | 126 ++++++++++++++++++++++ main/curl/CVE-2016-8623.patch | 207 ++++++++++++++++++++++++++++++++++++ main/curl/CVE-2016-8624-fixed.patch | 61 +++++++++++ 11 files changed, 1042 insertions(+), 4 deletions(-) create mode 100644 main/curl/CVE-2016-8615.patch create mode 100644 main/curl/CVE-2016-8616.patch create mode 100644 main/curl/CVE-2016-8617.patch create mode 100644 main/curl/CVE-2016-8618.patch create mode 100644 main/curl/CVE-2016-8619.patch create mode 100644 main/curl/CVE-2016-8620.patch create mode 100644 main/curl/CVE-2016-8621.patch create mode 100644 main/curl/CVE-2016-8622.patch create mode 100644 main/curl/CVE-2016-8623.patch create mode 100644 main/curl/CVE-2016-8624-fixed.patch diff --git a/main/curl/APKBUILD b/main/curl/APKBUILD index afb987f89c..1840fc5934 100644 --- a/main/curl/APKBUILD +++ b/main/curl/APKBUILD @@ -1,7 +1,8 @@ # Maintainer: Natanael Copa +# Contributor: Sergey Lukin pkgname=curl pkgver=7.49.1 -pkgrel=3 +pkgrel=4 pkgdesc="An URL retrival utility and library" url="http://curl.haxx.se" arch="all" @@ -17,6 +18,16 @@ source="http://curl.haxx.se/download/curl-$pkgver.tar.bz2 CVE-2016-5421.patch CVE-2016-7141.patch CVE-2016-7167.patch + CVE-2016-8615.patch + CVE-2016-8616.patch + CVE-2016-8617.patch + CVE-2016-8618.patch + CVE-2016-8619.patch + CVE-2016-8620.patch + CVE-2016-8621.patch + CVE-2016-8622.patch + CVE-2016-8623.patch + CVE-2016-8624-fixed.patch " _builddir="$srcdir/$pkgname-$pkgver" @@ -65,16 +76,46 @@ md5sums="6bb1f7af5b58b30e4e6414b8c1abccab curl-7.49.1.tar.bz2 150e3c110d6eb85187e109d04317b9e3 CVE-2016-5420.patch 0524664bc926374f6a7b057046924bd2 CVE-2016-5421.patch 7eada1e3745e3cfe8f4057dec273d820 CVE-2016-7141.patch -13d5ad6ce2db9b5a2314d31227577f1f CVE-2016-7167.patch" +13d5ad6ce2db9b5a2314d31227577f1f CVE-2016-7167.patch +21d1acf9c3a620215ba2fcabdbdf3d27 CVE-2016-8615.patch +b0cf6601cd685e5b5d10a10a22df1c8d CVE-2016-8616.patch +7f5775f33a18790e9b8d5c76a226bafe CVE-2016-8617.patch +152307bf8803c616ed5c6f6d06b2ee6a CVE-2016-8618.patch +a0883e93d4d4ba3611fd0bddfe5ac928 CVE-2016-8619.patch +80787be2354a8c6385164c66c97f7f61 CVE-2016-8620.patch +7640e8282f71c06f0079c1a19d9cff25 CVE-2016-8621.patch +dfbc8f4306dbaa4e6220d9c7dbaf691b CVE-2016-8622.patch +b7eedbdba069f8a3a6efaaddce1a38ed CVE-2016-8623.patch +efc92cc9dfe94f70b83aba2ed83d94b6 CVE-2016-8624-fixed.patch" sha256sums="eb63cec4bef692eab9db459033f409533e6d10e20942f4b060b32819e81885f1 curl-7.49.1.tar.bz2 d3499aaf331fca2303749bdffbedf5677a555a37ada187c1a734926c7cb718e5 CVE-2016-5419.patch 23e1fbd27860c6f46bec094c06b5618da2ab71b091945f587c0d7e8d143472f7 CVE-2016-5420.patch bca78667ac9110920c5ce31c8d82a784fe327eb184460c1b87fab4de004e6692 CVE-2016-5421.patch f097d6e5c75ebdaf532aef59e31790a657814bbb7e501dfb2eb6686ddca4f1eb CVE-2016-7141.patch -eedbd3b1f044bbc884140a75e40be0f97ea3d0df6a7bc7958db7ce0155642fcd CVE-2016-7167.patch" +eedbd3b1f044bbc884140a75e40be0f97ea3d0df6a7bc7958db7ce0155642fcd CVE-2016-7167.patch +6496aa6482eaae9187e6c03ea07197a02ae382c684b0ac00cf6c50c96cb16593 CVE-2016-8615.patch +2bc3733d06a647afe01513217c0943152fce1e8270f97c418ccd2ba0ddea4f01 CVE-2016-8616.patch +1860686d444f3710fc9c3b5aab66bedee8bf777516c905bf733a3d342b3034e0 CVE-2016-8617.patch +ff91898a935bc928407cac428bb26cfac2073ec8aba2cb38c005cfc2fec8fbfc CVE-2016-8618.patch +d89aefe4e4dc591b1e2341ee63b09d186bb85268ee7b3322d2c6c6100b89fc61 CVE-2016-8619.patch +dae2437923c77085d37d88ae5eced388eb2c924c02c0c4e0f8e44f8c8f2911db CVE-2016-8620.patch +05c014b25f25cfe689a1ce6d8238ef8906f0c6adfe64837e5b74691f0a5db287 CVE-2016-8621.patch +516a3cea6957c43513a4e55421d79ddfa26bbaf2adcbb42d7ec271ec583770d9 CVE-2016-8622.patch +f66764f7ade146f8df501d5a80be776d790b1d8d1e2f8775d892343fe87acfc1 CVE-2016-8623.patch +f53bf2d9d7dddc8c670ddd50aa6dcd32a9f45ffc13e17cd44df31e1127d942b2 CVE-2016-8624-fixed.patch" sha512sums="665ef178c282c14f429498547b3711ef79faf85f6db7f4ec24259e2c6247f6ee234dda158ebc207d03f08b5198c5844480e054f24f054b2de6c6a15d4f1ce6e6 curl-7.49.1.tar.bz2 a596e489b0b566d9dcc8292ccec4d90dfbeae7cb11e250871217ff90d1c9525d602f40e112eb0d47a0a597e5768c105423d1cb0cb2825c39a319ea9d582269d0 CVE-2016-5419.patch 9578f13c5d8e5a5d184b5b08dd7d59de596644084f2de04c025ad8cd78e11dadcff45bf4fab02b8942d7ed19977dec4d220893f675d64ed13b27284d63dfa5f1 CVE-2016-5420.patch 2b5e77dda11dbb77cbfe760da5377c94a1664b04f254c9fa642f49da119d93123ef6ee27e4c08d0ba9094240791ac09273c8be23fa8ca5982f8ed14d6b29ad7e CVE-2016-5421.patch 7eae8b37fb9ba8dfc0d6658b37191560668914a84aba411cfdac155bd1749b980514124c0653e85823a8a0e770f47ccc2a4177810b02cfc641c90f008639879e CVE-2016-7141.patch -c95d5711db08084e6a5c20ecd2c8aa8a494240a463940692b1d9e3a81ccb899894c1ac8ca65e35d7834352305bf8872c6e4907ff695e721824e8e7c1190f1863 CVE-2016-7167.patch" +c95d5711db08084e6a5c20ecd2c8aa8a494240a463940692b1d9e3a81ccb899894c1ac8ca65e35d7834352305bf8872c6e4907ff695e721824e8e7c1190f1863 CVE-2016-7167.patch +03f473805bc392c7c8d1336abb69817159ed2892220de81afab36f9d7c479bf6f01a5c5f90d93e7076dc1cd855e11c591e393bd3f125a671221cade1455b62d1 CVE-2016-8615.patch +865629b296b0cec5bb774cf46d86b3e69b1c20f1176feec3c945c54fa7e11f944b86df2a65e72fefb8a75856d514640818f646a346bf68081dcf5a0b283c14ac CVE-2016-8616.patch +b020c27e9e2752580c6af1a890785bfc1307865e70bd00a7133ee495b27a6b112e7ec670b824c342d2cc56d6d6afa0387e963d59a18fcc3d724f85d1f7a9e97d CVE-2016-8617.patch +ef7c7552057d7094282fa2eb430f146a2e843dc79b13decbf7bd7f44c9ddd8b5fc3d0e5a7f7642eada048373c0847ea61bfc0f284ed66980ec15d24e637a195b CVE-2016-8618.patch +c414da5ffff46f6eae70cde90bef7a691c09364fbb1347e459ac63a2a3a549fe23e1e19490f055b97660ea238e2b08ed879382944794769ada9d89ba53294428 CVE-2016-8619.patch +68b6312f006f5ff3e7ff42b96693ba5d48889a0cee485f3b97a05f9b47b46b9502490e3feda527902b080e905e45c4d6b6d122fb6cc375bc21b30d086d841e76 CVE-2016-8620.patch +7c90a1b2666aa9acf05744d30f4342ed0a8f7297786e7ed46d15257e2d810296698281be6a76f946ad39368a66338cb5317651014d60296bb2145967e1396a46 CVE-2016-8621.patch +851ce886f2cffec50a4383d9ab8b753204ac64ef7b7bb47f9dd4914daaf1b6d5d8ae4bbddaaf1e48a323fd0eeff40a264299639129ec755dba8d04382a50e0e5 CVE-2016-8622.patch +782f31b92a56807e232a12328c5ddf9b9587117e25f730c440f6fa40c72501cdd41b61f367314b3b2de44b394605f4a6763dbe84a3c2f0b5dbf1ccbc882e3952 CVE-2016-8623.patch +c1b5ebce13e9ea7da611f5eee43bf3cf28034dd0e00877494c04459dd24f3b56e8501470bb06f210afda86e57c9ffbe61bc9cdeb9c8659cb4415b7f715f6aac7 CVE-2016-8624-fixed.patch" diff --git a/main/curl/CVE-2016-8615.patch b/main/curl/CVE-2016-8615.patch new file mode 100644 index 0000000000..d1fda35a9b --- /dev/null +++ b/main/curl/CVE-2016-8615.patch @@ -0,0 +1,75 @@ +From 1620f552a277ed5b23a48b9c27dbf07663cac068 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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(-) + +diff --git a/lib/cookie.c b/lib/cookie.c +index 0f05da2..e5097d3 100644 +--- a/lib/cookie.c ++++ b/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 + diff --git a/main/curl/CVE-2016-8616.patch b/main/curl/CVE-2016-8616.patch new file mode 100644 index 0000000000..67309bf97f --- /dev/null +++ b/main/curl/CVE-2016-8616.patch @@ -0,0 +1,66 @@ +From cef510beb222ab5750afcac2c74fcbcdc31ada64 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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(-) + +diff --git a/lib/url.c b/lib/url.c +index 91b2bf8..cd3335c 100644 +--- a/lib/url.c ++++ b/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,12 +3477,12 @@ ConnectionExists(struct Curl_easy *data, + if(wantProxyNTLMhttp) { + /* Both check->proxyuser and check->proxypasswd can be NULL */ + if(!check->proxyuser || !check->proxypasswd) + continue; + +- 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 + diff --git a/main/curl/CVE-2016-8617.patch b/main/curl/CVE-2016-8617.patch new file mode 100644 index 0000000000..66c7f9ac61 --- /dev/null +++ b/main/curl/CVE-2016-8617.patch @@ -0,0 +1,36 @@ +From 3599341dd611303ee9544839d30f603f606d1082 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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(+) + +diff --git a/lib/base64.c b/lib/base64.c +index ad25459..204a227 100644 +--- a/lib/base64.c ++++ b/lib/base64.c +@@ -188,10 +188,15 @@ static CURLcode base64_encode(const char *table64, + *outlen = 0; + + if(!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(!output) + return CURLE_OUT_OF_MEMORY; + + /* +-- +2.9.3 + diff --git a/main/curl/CVE-2016-8618.patch b/main/curl/CVE-2016-8618.patch new file mode 100644 index 0000000000..6d4eaaf9d6 --- /dev/null +++ b/main/curl/CVE-2016-8618.patch @@ -0,0 +1,50 @@ +From 31106a073882656a2a5ab56c4ce2847e9a334c3c Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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(-) + +diff --git a/lib/mprintf.c b/lib/mprintf.c +index dbedeaa..2c88aa8 100644 +--- a/lib/mprintf.c ++++ b/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 + diff --git a/main/curl/CVE-2016-8619.patch b/main/curl/CVE-2016-8619.patch new file mode 100644 index 0000000000..8470b359bb --- /dev/null +++ b/main/curl/CVE-2016-8619.patch @@ -0,0 +1,50 @@ +From 91239f7040b1f026d4d15765e7e3f58e92e93761 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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(-) + +diff --git a/lib/security.c b/lib/security.c +index a268d4a..4cef8f8 100644 +--- a/lib/security.c ++++ b/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 + diff --git a/main/curl/CVE-2016-8620.patch b/main/curl/CVE-2016-8620.patch new file mode 100644 index 0000000000..c8c2cd1010 --- /dev/null +++ b/main/curl/CVE-2016-8620.patch @@ -0,0 +1,205 @@ +From 52f3e1d1092c81a4f574c9fc6cb3818b88434c8d Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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(+) + +diff --git a/src/tool_urlglob.c b/src/tool_urlglob.c +index a357b8b..64c75ba 100644 +--- a/src/tool_urlglob.c ++++ b/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,10 +281,11 @@ 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) + /* 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 +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(-) + +diff --git a/src/tool_urlglob.c b/src/tool_urlglob.c +index 64c75ba..c45a78b 100644 +--- a/src/tool_urlglob.c ++++ b/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 +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(-) + +diff --git a/src/tool_urlglob.c b/src/tool_urlglob.c +index c45a78b..09d21b6 100644 +--- a/src/tool_urlglob.c ++++ b/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 + diff --git a/main/curl/CVE-2016-8621.patch b/main/curl/CVE-2016-8621.patch new file mode 100644 index 0000000000..6855ce957b --- /dev/null +++ b/main/curl/CVE-2016-8621.patch @@ -0,0 +1,121 @@ +From 8a6d9ded5f02f0294ae63a007e26087316c1998e Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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(-) + +diff --git a/lib/parsedate.c b/lib/parsedate.c +index dfcf855..8e932f4 100644 +--- a/lib/parsedate.c ++++ b/lib/parsedate.c +@@ -3,11 +3,11 @@ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2014, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2016, Daniel Stenberg, , 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; +diff --git a/tests/data/test517 b/tests/data/test517 +index c81a45e..513634f 100644 +--- a/tests/data/test517 ++++ b/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 + + + # 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 +diff --git a/tests/libtest/lib517.c b/tests/libtest/lib517.c +index 2f68ebd..22162ff 100644 +--- a/tests/libtest/lib517.c ++++ b/tests/libtest/lib517.c +@@ -3,11 +3,11 @@ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2016, Daniel Stenberg, , 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 + diff --git a/main/curl/CVE-2016-8622.patch b/main/curl/CVE-2016-8622.patch new file mode 100644 index 0000000000..e6dba69b91 --- /dev/null +++ b/main/curl/CVE-2016-8622.patch @@ -0,0 +1,126 @@ +From 71da91453899ba20b28ee9712620e323145a0ee5 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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(-) + +diff --git a/docs/libcurl/curl_easy_unescape.3 b/docs/libcurl/curl_easy_unescape.3 +index 06fd6fc..50ce97d 100644 +--- a/docs/libcurl/curl_easy_unescape.3 ++++ b/docs/libcurl/curl_easy_unescape.3 +@@ -3,11 +3,11 @@ + .\" * Project ___| | | | _ \| | + .\" * / __| | | | |_) | | + .\" * | (__| |_| | _ <| |___ + .\" * \___|\___/|_| \_\_____| + .\" * +-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. ++.\" * Copyright (C) 1998 - 2016, Daniel Stenberg, , 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 +diff --git a/lib/dict.c b/lib/dict.c +index a7b5965..48a4e0a 100644 +--- a/lib/dict.c ++++ b/lib/dict.c +@@ -3,11 +3,11 @@ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2015, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2016, Daniel Stenberg, , 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 + #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 +diff --git a/lib/escape.c b/lib/escape.c +index e61260d..6657007 100644 +--- a/lib/escape.c ++++ b/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 + diff --git a/main/curl/CVE-2016-8623.patch b/main/curl/CVE-2016-8623.patch new file mode 100644 index 0000000000..4eb86782e6 --- /dev/null +++ b/main/curl/CVE-2016-8623.patch @@ -0,0 +1,207 @@ +From d9d57fe0da6f25d05570fd583520ecd321ed9c3f Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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(-) + +diff --git a/lib/cookie.c b/lib/cookie.c +index 0f05da2..8607ce3 100644 +--- a/lib/cookie.c ++++ b/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() +diff --git a/lib/cookie.h b/lib/cookie.h +index cd7c54a..a9a4578 100644 +--- a/lib/cookie.h ++++ b/lib/cookie.h +@@ -5,11 +5,11 @@ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * +- * Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. ++ * Copyright (C) 1998 - 2016, Daniel Stenberg, , 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 +diff --git a/lib/http.c b/lib/http.c +index 65c145a..e6e7d37 100644 +--- a/lib/http.c ++++ b/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 + diff --git a/main/curl/CVE-2016-8624-fixed.patch b/main/curl/CVE-2016-8624-fixed.patch new file mode 100644 index 0000000000..b288f9ecda --- /dev/null +++ b/main/curl/CVE-2016-8624-fixed.patch @@ -0,0 +1,61 @@ +From 6604d4df30aec66db6f5bd51ee3c341dd7329fcf Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +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(-) + +diff --git a/lib/url.c b/lib/url.c +index 91b2bf8..98236e2 100644 +--- +Patch was slightly modified by Sergey Lukin +Original patch (https://curl.haxx.se/CVE-2016-8624.patch) failed to apply to +curl 7.49.1 + +--- a/lib/url.c ++++ b/lib/url.c +@@ -4144,7 +4144,7 @@ + path[0]=0; + + if(2 > sscanf(data->change.url, +- "%15[^\n:]://%[^\n/?]%[^\n]", ++ "%15[^\n:]://%[^\n/?#]%[^\n]", + protobuf, + conn->host.name, path)) { + +@@ -4152,7 +4152,7 @@ + * 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. +@@ -4242,10 +4242,10 @@ + } + + /* 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. */ + -- cgit v1.2.3