diff --git a/SOURCES/0061-curl-7.29.0-CVE-2018-1000122.patch b/SOURCES/0061-curl-7.29.0-CVE-2018-1000122.patch index 74e9fa7..c8b38ae 100644 --- a/SOURCES/0061-curl-7.29.0-CVE-2018-1000122.patch +++ b/SOURCES/0061-curl-7.29.0-CVE-2018-1000122.patch @@ -1,7 +1,7 @@ From 9f163418fabbe6219ab04cfe9bf81d2f33bd54d7 Mon Sep 17 00:00:00 2001 From: Richy Kim Date: Tue, 20 Dec 2016 05:48:15 -0500 -Subject: [PATCH 1/7] CURLOPT_BUFFERSIZE: support enlarging receive buffer +Subject: [PATCH 01/18] CURLOPT_BUFFERSIZE: support enlarging receive buffer Replace use of fixed macro BUFSIZE to define the size of the receive buffer. Reappropriate CURLOPT_BUFFERSIZE to include enlarging receive @@ -270,7 +270,7 @@ index 7431825..a7807cf 100644 From f175a713c964d351012baaf8c78c1b468cc6aba0 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 24 Apr 2017 15:33:57 +0200 -Subject: [PATCH 2/7] http: use private user:password output buffer +Subject: [PATCH 02/18] http: use private user:password output buffer Don't clobber the receive buffer. @@ -346,7 +346,7 @@ index f4368c4..12e7dc3 100644 From 6ff175806c338223a2a9a69f6ae8ae2b91dc2b56 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 24 Apr 2017 16:05:46 +0200 -Subject: [PATCH 3/7] ftp: use private buffer for temp storage, not receive +Subject: [PATCH 03/18] ftp: use private buffer for temp storage, not receive buffer Upstream-commit: 349789e645a306a6ee467ef90a57f6cc306ca92e @@ -444,7 +444,7 @@ index 730b695..10a21ce 100644 From b67324919089fc4f9bb7a38a6a31174883a4bc24 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 Apr 2017 00:09:22 +0200 -Subject: [PATCH 4/7] CURLOPT_BUFFERSIZE: 1024 bytes is now the minimum size +Subject: [PATCH 04/18] CURLOPT_BUFFERSIZE: 1024 bytes is now the minimum size The buffer is needed to receive FTP, HTTP CONNECT responses etc so already at this size things risk breaking and smaller is certainly not @@ -512,7 +512,7 @@ index a7807cf..cd96e8f 100644 From 9798012315c087168c5a4a1dc56eacfe82c69626 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 Apr 2017 00:15:28 +0200 -Subject: [PATCH 5/7] file: use private buffer for C-L output +Subject: [PATCH 05/18] file: use private buffer for C-L output ... instead of clobbering the download buffer. @@ -555,7 +555,7 @@ index 1ad4758..b6bf18e 100644 From f4868e737e9f8d719cb9897506da2c7f92dfd87d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 25 Apr 2017 00:16:10 +0200 -Subject: [PATCH 6/7] buffer_size: make sure it always has the correct size +Subject: [PATCH 06/18] buffer_size: make sure it always has the correct size Removes the need for CURL_BUFSIZE @@ -623,11 +623,1007 @@ index cd96e8f..fbe69c2 100644 2.14.3 +From 43d9e7acc44c9849f85882d2ec18c2a609f90809 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 00:48:56 +0200 +Subject: [PATCH 07/18] http: don't clobber the receive buffer for timecond + +Upstream-commit: 87eb8d5b30ce2adfe2673cc0b1abf6ca68891cc4 +Signed-off-by: Kamil Dudka +--- + lib/http.c | 37 +++++++++++++++++++------------------ + 1 file changed, 19 insertions(+), 18 deletions(-) + +diff --git a/lib/http.c b/lib/http.c +index 12e7dc3..6ecdda2 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -1607,9 +1607,10 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data, + Curl_send_buffer *req_buffer) + { + const struct tm *tm; +- char *buf = data->state.buffer; + CURLcode result = CURLE_OK; + struct tm keeptime; ++ char datestr[80]; ++ const char *condp; + + result = Curl_gmtime(data->set.timevalue, &keeptime); + if(result) { +@@ -1618,6 +1619,19 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data, + } + tm = &keeptime; + ++ switch(data->set.timecondition) { ++ default: ++ case CURL_TIMECOND_IFMODSINCE: ++ condp = "If-Modified-Since"; ++ break; ++ case CURL_TIMECOND_IFUNMODSINCE: ++ condp = "If-Unmodified-Since"; ++ break; ++ case CURL_TIMECOND_LASTMOD: ++ condp = "Last-Modified"; ++ break; ++ } ++ + /* The If-Modified-Since header family should have their times set in + * GMT as RFC2616 defines: "All HTTP date/time stamps MUST be + * represented in Greenwich Mean Time (GMT), without exception. For the +@@ -1626,8 +1640,9 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data, + */ + + /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */ +- snprintf(buf, BUFSIZE-1, +- "%s, %02d %s %4d %02d:%02d:%02d GMT", ++ snprintf(datestr, sizeof(datestr), ++ "%s: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n", ++ condp, + Curl_wkday[tm->tm_wday?tm->tm_wday-1:6], + tm->tm_mday, + Curl_month[tm->tm_mon], +@@ -1636,21 +1651,7 @@ CURLcode Curl_add_timecondition(struct SessionHandle *data, + tm->tm_min, + tm->tm_sec); + +- switch(data->set.timecondition) { +- case CURL_TIMECOND_IFMODSINCE: +- default: +- result = Curl_add_bufferf(req_buffer, +- "If-Modified-Since: %s\r\n", buf); +- break; +- case CURL_TIMECOND_IFUNMODSINCE: +- result = Curl_add_bufferf(req_buffer, +- "If-Unmodified-Since: %s\r\n", buf); +- break; +- case CURL_TIMECOND_LASTMOD: +- result = Curl_add_bufferf(req_buffer, +- "Last-Modified: %s\r\n", buf); +- break; +- } ++ result = Curl_add_buffer(req_buffer, datestr, strlen(datestr)); + + return result; + } +-- +2.17.2 + + +From 91ca8ea3e4e984070ef07dbc1a7258ced3b6982a Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 00:50:04 +0200 +Subject: [PATCH 08/18] pingpong: use the set buffer size + +Upstream-commit: b8191e975faa7810ed3d858205b0b3f0d297f0b2 +Signed-off-by: Kamil Dudka +--- + lib/pingpong.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/lib/pingpong.c b/lib/pingpong.c +index 16b4ad3..c4666fe 100644 +--- a/lib/pingpong.c ++++ b/lib/pingpong.c +@@ -309,7 +309,8 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd, + + keepon=TRUE; + +- while((pp->nread_respnread_resp < (size_t)data->set.buffer_size) && ++ (keepon && !result)) { + + if(pp->cache) { + /* we had data in the "cache", copy that instead of doing an actual +@@ -319,7 +320,7 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd, + * it would have been populated with something of size int to begin + * with, even though its datatype may be larger than an int. + */ +- DEBUGASSERT((ptr+pp->cache_size) <= (buf+BUFSIZE+1)); ++ DEBUGASSERT((ptr+pp->cache_size) <= (buf+data->set.buffer_size+1)); + memcpy(ptr, pp->cache, pp->cache_size); + gotbytes = (ssize_t)pp->cache_size; + free(pp->cache); /* free the cache */ +@@ -332,8 +333,10 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd, + enum protection_level prot = conn->data_prot; + conn->data_prot = PROT_CLEAR; + #endif +- DEBUGASSERT((ptr+BUFSIZE-pp->nread_resp) <= (buf+BUFSIZE+1)); +- res = Curl_read(conn, sockfd, ptr, BUFSIZE-pp->nread_resp, ++ DEBUGASSERT((ptr + data->set.buffer_size - pp->nread_resp) <= ++ (buf + data->set.buffer_size + 1)); ++ res = Curl_read(conn, sockfd, ptr, ++ data->set.buffer_size - pp->nread_resp, + &gotbytes); + #if defined(HAVE_KRB4) || defined(HAVE_GSSAPI) + DEBUGASSERT(prot > PROT_NONE && prot < PROT_LAST); +@@ -430,7 +433,7 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd, + } + else if(keepon) { + +- if((perline == gotbytes) && (gotbytes > BUFSIZE/2)) { ++ if((perline == gotbytes) && (gotbytes > data->set.buffer_size/2)) { + /* We got an excessive line without newlines and we need to deal + with it. We keep the first bytes of the line then we throw + away the rest. */ +@@ -442,7 +445,7 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd, + interested in the first piece */ + clipamount = 40; + } +- else if(pp->nread_resp > BUFSIZE/2) { ++ else if(pp->nread_resp > (size_t)data->set.buffer_size/2) { + /* We got a large chunk of data and there's potentially still + trailing data to take care of, so we put any such part in the + "cache", clear the buffer to make space and restart. */ +-- +2.17.2 + + +From 3bc2bc2f1c5e3afd7a7cbd208d97fbb37f2dfc5f Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 00:50:21 +0200 +Subject: [PATCH 09/18] failf: use private buffer, don't clobber receive buffer + +Upstream-commit: f2fadf490f66ad364f5a6f0356d626dda5f9a82f +Signed-off-by: Kamil Dudka +--- + lib/sendf.c | 15 +++++++-------- + 1 file changed, 7 insertions(+), 8 deletions(-) + +diff --git a/lib/sendf.c b/lib/sendf.c +index c64d686..403025b 100644 +--- a/lib/sendf.c ++++ b/lib/sendf.c +@@ -155,21 +155,20 @@ void Curl_failf(struct SessionHandle *data, const char *fmt, ...) + { + va_list ap; + size_t len; ++ char error[CURL_ERROR_SIZE + 2]; + va_start(ap, fmt); + +- vsnprintf(data->state.buffer, BUFSIZE, fmt, ap); ++ vsnprintf(error, CURL_ERROR_SIZE, fmt, ap); ++ len = strlen(error); + + if(data->set.errorbuffer && !data->state.errorbuf) { +- snprintf(data->set.errorbuffer, CURL_ERROR_SIZE, "%s", data->state.buffer); ++ strcpy(data->set.errorbuffer, error); + data->state.errorbuf = TRUE; /* wrote error string */ + } + if(data->set.verbose) { +- len = strlen(data->state.buffer); +- if(len < BUFSIZE - 1) { +- data->state.buffer[len] = '\n'; +- data->state.buffer[++len] = '\0'; +- } +- Curl_debug(data, CURLINFO_TEXT, data->state.buffer, len, NULL); ++ error[len] = '\n'; ++ error[++len] = '\0'; ++ Curl_debug(data, CURLINFO_TEXT, error, len, NULL); + } + + va_end(ap); +-- +2.17.2 + + +From 0a1107c2ad898e837f0aa4742c1b17ef186a3243 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 00:50:50 +0200 +Subject: [PATCH 10/18] transfer: fix minor buffer_size mistake + +Upstream-commit: 40a074f255de90003ab753f5d0ad61b74c62ca9b +Signed-off-by: Kamil Dudka +--- + lib/transfer.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/lib/transfer.c b/lib/transfer.c +index dff6838..9b932de 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -385,8 +385,7 @@ static CURLcode readwrite_data(struct SessionHandle *data, + /* This is where we loop until we have read everything there is to + read or we get a CURLE_AGAIN */ + do { +- size_t buffersize = data->set.buffer_size? +- data->set.buffer_size : BUFSIZE; ++ size_t buffersize = data->set.buffer_size; + size_t bytestoread = buffersize; + + if(k->size != -1 && !k->header) { +-- +2.17.2 + + +From 15408839da1b768974650bdf187c749432fdaefa Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 01:03:17 +0200 +Subject: [PATCH 11/18] http-proxy: use a dedicated CONNECT response buffer + +To make it suitably independent of the receive buffer and its flexible +size. + +Upstream-commit: 0cab3a394a190c1cdf900cf2887ccdd6a7f213ef +Signed-off-by: Kamil Dudka +--- + lib/http_proxy.c | 69 +++++++++++++++++++++++++++++++++++------------- + lib/url.c | 1 + + lib/urldata.h | 3 ++- + 3 files changed, 53 insertions(+), 20 deletions(-) + +diff --git a/lib/http_proxy.c b/lib/http_proxy.c +index 4ab280f..13fb228 100644 +--- a/lib/http_proxy.c ++++ b/lib/http_proxy.c +@@ -83,20 +83,13 @@ CURLcode Curl_proxy_connect(struct connectdata *conn) + return CURLE_OK; + } + +-/* +- * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This +- * function will issue the necessary commands to get a seamless tunnel through +- * this proxy. After that, the socket can be used just as a normal socket. +- * +- * 'blocking' set to TRUE means that this function will do the entire CONNECT +- * + response in a blocking fashion. Should be avoided! +- */ ++#define CONNECT_BUFFER_SIZE 16384 + +-CURLcode Curl_proxyCONNECT(struct connectdata *conn, +- int sockindex, +- const char *hostname, +- unsigned short remote_port, +- bool blocking) ++CURLcode CONNECT(struct connectdata *conn, ++ int sockindex, ++ const char *hostname, ++ unsigned short remote_port, ++ bool blocking) + { + int subversion=0; + struct SessionHandle *data=conn->data; +@@ -253,14 +246,19 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + char *ptr; + char *line_start; + +- ptr=data->state.buffer; ++ ptr = conn->connect_buffer; + line_start = ptr; + + nread=0; + perline=0; + keepon=TRUE; + +- while((nread= &conn->connect_buffer[CONNECT_BUFFER_SIZE]) { ++ failf(data, "CONNECT response too large!"); ++ return CURLE_RECV_ERROR; ++ } + + check = Curl_timeleft(data, NULL, TRUE); + if(check <= 0) { +@@ -279,8 +277,8 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + case 0: /* timeout */ + break; + default: +- DEBUGASSERT(ptr+BUFSIZE-nread <= data->state.buffer+BUFSIZE+1); +- result = Curl_read(conn, tunnelsocket, ptr, BUFSIZE-nread, ++ result = Curl_read(conn, tunnelsocket, ptr, ++ CONNECT_BUFFER_SIZE - nread, + &gotbytes); + if(result==CURLE_AGAIN) + continue; /* go loop yourself */ +@@ -313,7 +311,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + /* This means we are currently ignoring a response-body */ + + nread = 0; /* make next read start over in the read buffer */ +- ptr=data->state.buffer; ++ ptr = conn->connect_buffer; + if(cl) { + /* A Content-Length based body: simply count down the counter + and make sure to break out of the loop when we're done! */ +@@ -386,7 +384,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + /* end of response-headers from the proxy */ + nread = 0; /* make next read start over in the read + buffer */ +- ptr=data->state.buffer; ++ ptr = conn->connect_buffer; + if((407 == k->httpcode) && !data->state.authproblem) { + /* If we get a 407 response code with content length + when we have no auth problem, we must ignore the +@@ -585,4 +583,37 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn, + data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */ + return CURLE_OK; + } ++ ++/* ++ * Curl_proxyCONNECT() requires that we're connected to a HTTP proxy. This ++ * function will issue the necessary commands to get a seamless tunnel through ++ * this proxy. After that, the socket can be used just as a normal socket. ++ * ++ * 'blocking' set to TRUE means that this function will do the entire CONNECT ++ * + response in a blocking fashion. Should be avoided! ++ */ ++ ++CURLcode Curl_proxyCONNECT(struct connectdata *conn, ++ int sockindex, ++ const char *hostname, ++ unsigned short remote_port, ++ bool blocking) ++{ ++ CURLcode result; ++ if(TUNNEL_INIT == conn->tunnel_state[sockindex]) { ++ if(!conn->connect_buffer) { ++ conn->connect_buffer = malloc(CONNECT_BUFFER_SIZE); ++ if(!conn->connect_buffer) ++ return CURLE_OUT_OF_MEMORY; ++ } ++ } ++ result = CONNECT(conn, sockindex, hostname, remote_port, blocking); ++ ++ if(result || (TUNNEL_COMPLETE == conn->tunnel_state[sockindex])) ++ Curl_safefree(conn->connect_buffer); ++ ++ return result; ++} ++ ++ + #endif /* CURL_DISABLE_PROXY */ +diff --git a/lib/url.c b/lib/url.c +index 00fd15d..b86243b 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -2523,6 +2523,7 @@ static void conn_free(struct connectdata *conn) + Curl_safefree(conn->host.rawalloc); /* host name buffer */ + Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ + Curl_safefree(conn->master_buffer); ++ Curl_safefree(conn->connect_buffer); + + Curl_llist_destroy(conn->send_pipe, NULL); + Curl_llist_destroy(conn->recv_pipe, NULL); +diff --git a/lib/urldata.h b/lib/urldata.h +index fbe69c2..c362c58 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -1018,7 +1018,8 @@ struct connectdata { + TUNNEL_COMPLETE /* CONNECT response received completely */ + } tunnel_state[2]; /* two separate ones to allow FTP */ + +- struct connectbundle *bundle; /* The bundle we are member of */ ++ struct connectbundle *bundle; /* The bundle we are member of */ ++ char *connect_buffer; /* for CONNECT business */ + }; + + /* The end of connectdata. */ +-- +2.17.2 + + +From 1122ecc4b522f24d466bcc2e658dd098a32d982f Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 14:37:06 +0200 +Subject: [PATCH 12/18] upload: UPLOAD_BUFSIZE is now for the upload buffer + +Upstream-commit: 89cf6f38d2f525cbc8537a60061f5f37bb2f35f7 +Signed-off-by: Kamil Dudka +--- + lib/file.c | 2 +- + lib/transfer.c | 2 +- + lib/urldata.h | 6 +++++- + 3 files changed, 7 insertions(+), 3 deletions(-) + +diff --git a/lib/file.c b/lib/file.c +index 98536cd..2f2e466 100644 +--- a/lib/file.c ++++ b/lib/file.c +@@ -364,7 +364,7 @@ static CURLcode file_upload(struct connectdata *conn) + + while(res == CURLE_OK) { + int readcount; +- res = Curl_fillreadbuffer(conn, BUFSIZE, &readcount); ++ res = Curl_fillreadbuffer(conn, (int)data->set.buffer_size, &readcount); + if(res) + break; + +diff --git a/lib/transfer.c b/lib/transfer.c +index 9b932de..b707f8a 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -835,7 +835,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data, + sending_http_headers = FALSE; + } + +- result = Curl_fillreadbuffer(conn, BUFSIZE, &fillcount); ++ result = Curl_fillreadbuffer(conn, UPLOAD_BUFSIZE, &fillcount); + if(result) + return result; + +diff --git a/lib/urldata.h b/lib/urldata.h +index c362c58..afe37c0 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -200,6 +200,10 @@ + #define MAX_BUFSIZE CURL_MAX_READ_SIZE + #define MIN_BUFSIZE 1024 + ++/* The upload buffer size, should not be smaller than CURL_MAX_WRITE_SIZE, as ++ it needs to hold a full buffer as could be sent in a write callback */ ++#define UPLOAD_BUFSIZE CURL_MAX_WRITE_SIZE ++ + /* Initial size of the buffer to store headers in, it'll be enlarged in case + of need. */ + #define HEADERSIZE 256 +@@ -1179,7 +1183,7 @@ struct UrlState { + size_t headersize; /* size of the allocation */ + + char *buffer; /* download buffer */ +- char uploadbuffer[BUFSIZE+1]; /* upload buffer */ ++ char uploadbuffer[UPLOAD_BUFSIZE+1]; /* upload buffer */ + curl_off_t current_speed; /* the ProgressShow() funcion sets this, + bytes / second */ + bool this_is_a_follow; /* this is a followed Location: request */ +-- +2.17.2 + + +From 4666a96fce7a2aa8c294cef7aec23e39a3d49673 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 14:37:45 +0200 +Subject: [PATCH 13/18] krb5: use private buffer for temp string, not receive + buffer + +Upstream-commit: c79f4908d461cecaa9976099dcbb8a63b351f19e +Signed-off-by: Kamil Dudka +--- + lib/krb5.c | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +diff --git a/lib/krb5.c b/lib/krb5.c +index 1e99c70..e4eb0b0 100644 +--- a/lib/krb5.c ++++ b/lib/krb5.c +@@ -174,6 +174,7 @@ krb5_auth(void *app_data, struct connectdata *conn) + gss_ctx_id_t *context = app_data; + struct gss_channel_bindings_struct chan; + size_t base64_sz = 0; ++ char *stringp; + + if(getsockname(conn->sock[FIRSTSOCKET], + (struct sockaddr *)LOCAL_ADDR, &l) < 0) +@@ -205,16 +206,19 @@ krb5_auth(void *app_data, struct connectdata *conn) + return -1; + } + +- input_buffer.value = data->state.buffer; +- input_buffer.length = snprintf(input_buffer.value, BUFSIZE, "%s@%s", +- service, host); ++ stringp = aprintf("%s@%s", service, host); ++ if(!stringp) ++ return -2; ++ ++ input_buffer.value = stringp; ++ input_buffer.length = strlen(stringp); + maj = gss_import_name(&min, &input_buffer, GSS_C_NT_HOSTBASED_SERVICE, + &gssname); ++ free(stringp); + if(maj != GSS_S_COMPLETE) { + gss_release_name(&min, &gssname); + if(service == srv_host) { +- Curl_failf(data, "Error importing service name %s", +- input_buffer.value); ++ Curl_failf(data, "Error importing service name %s@%s", service, host); + return AUTH_ERROR; + } + service = srv_host; +-- +2.17.2 + + +From 4725e3cbe9af074304a4735b6ac667a154081b99 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 14:38:34 +0200 +Subject: [PATCH 14/18] buffer: use data->set.buffer_size instead of BUFSIZE + +... to properly use the dynamically set buffer size! + +Upstream-commit: e40e9d7f0decc799e3ccfe2c418632f8bb52031a +Signed-off-by: Kamil Dudka +--- + lib/file.c | 4 ++-- + lib/ftp.c | 5 +++-- + lib/http.c | 7 ++++--- + lib/sendf.c | 9 ++++----- + lib/smtp.c | 2 +- + lib/ssh.c | 5 +++-- + lib/telnet.c | 10 +++++----- + lib/transfer.c | 4 +--- + 8 files changed, 23 insertions(+), 23 deletions(-) + +diff --git a/lib/file.c b/lib/file.c +index 2f2e466..ddac28f 100644 +--- a/lib/file.c ++++ b/lib/file.c +@@ -558,8 +558,8 @@ static CURLcode file_do(struct connectdata *conn, bool *done) + while(res == CURLE_OK) { + /* Don't fill a whole buffer if we want less than all data */ + size_t bytestoread = +- (expected_size < CURL_OFF_T_C(BUFSIZE) - CURL_OFF_T_C(1)) ? +- curlx_sotouz(expected_size) : BUFSIZE - 1; ++ (expected_size < data->set.buffer_size) ? ++ curlx_sotouz(expected_size) : (size_t)data->set.buffer_size; + + nread = read(fd, buf, bytestoread); + +diff --git a/lib/ftp.c b/lib/ftp.c +index c40d7e4..3a8b4b2 100644 +--- a/lib/ftp.c ++++ b/lib/ftp.c +@@ -1646,8 +1646,9 @@ static CURLcode ftp_state_ul_setup(struct connectdata *conn, + curl_off_t passed=0; + do { + size_t readthisamountnow = +- (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ? +- BUFSIZE : curlx_sotouz(data->state.resume_from - passed); ++ (data->state.resume_from - passed > data->set.buffer_size) ? ++ (size_t)data->set.buffer_size : ++ curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread = + conn->fread_func(data->state.buffer, 1, readthisamountnow, +diff --git a/lib/http.c b/lib/http.c +index 6ecdda2..665447b 100644 +--- a/lib/http.c ++++ b/lib/http.c +@@ -1061,7 +1061,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in, + buffer is using this size. + */ + +- sendsize= (size > CURL_MAX_WRITE_SIZE)?CURL_MAX_WRITE_SIZE:size; ++ sendsize = CURLMIN(size, CURL_MAX_WRITE_SIZE); + + /* OpenSSL is very picky and we must send the SAME buffer pointer to the + library when we attempt to re-send this buffer. Sending the same data +@@ -2036,8 +2036,9 @@ CURLcode Curl_http(struct connectdata *conn, bool *done) + curl_off_t passed=0; + do { + size_t readthisamountnow = +- (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ? +- BUFSIZE : curlx_sotouz(data->state.resume_from - passed); ++ (data->state.resume_from - passed > data->set.buffer_size) ? ++ (size_t)data->set.buffer_size : ++ curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread = + data->set.fread_func(data->state.buffer, 1, readthisamountnow, +diff --git a/lib/sendf.c b/lib/sendf.c +index 403025b..fb0e6e8 100644 +--- a/lib/sendf.c ++++ b/lib/sendf.c +@@ -528,7 +528,8 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */ + ssize_t nread = 0; + size_t bytesfromsocket = 0; + char *buffertofill = NULL; +- bool pipelining = (conn->data->multi && ++ struct SessionHandle *data = conn->data; ++ bool pipelining = (data->multi && + Curl_multi_canPipeline(conn->data->multi)) ? TRUE : FALSE; + + /* Set 'num' to 0 or 1, depending on which socket that has been sent here. +@@ -554,13 +555,11 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */ + } + /* If we come here, it means that there is no data to read from the buffer, + * so we read from the socket */ +- bytesfromsocket = CURLMIN(sizerequested, BUFSIZE * sizeof (char)); ++ bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size); + buffertofill = conn->master_buffer; + } + else { +- bytesfromsocket = CURLMIN((long)sizerequested, +- conn->data->set.buffer_size ? +- conn->data->set.buffer_size : BUFSIZE); ++ bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size); + buffertofill = buf; + } + +diff --git a/lib/smtp.c b/lib/smtp.c +index d2d4aeb..ccc2dc7 100644 +--- a/lib/smtp.c ++++ b/lib/smtp.c +@@ -1665,7 +1665,7 @@ CURLcode Curl_smtp_escape_eob(struct connectdata *conn, ssize_t nread) + + /* Do we need to allocate the scatch buffer? */ + if(!data->state.scratch) { +- data->state.scratch = malloc(2 * BUFSIZE); ++ data->state.scratch = malloc(2 * data->set.buffer_size); + + if(!data->state.scratch) { + failf (data, "Failed to alloc scratch buffer!"); +diff --git a/lib/ssh.c b/lib/ssh.c +index 589d4a3..169ef1b 100644 +--- a/lib/ssh.c ++++ b/lib/ssh.c +@@ -1711,8 +1711,9 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) + curl_off_t passed=0; + do { + size_t readthisamountnow = +- (data->state.resume_from - passed > CURL_OFF_T_C(BUFSIZE)) ? +- BUFSIZE : curlx_sotouz(data->state.resume_from - passed); ++ (data->state.resume_from - passed > data->set.buffer_size) ? ++ data->set.buffer_size : ++ curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread = + conn->fread_func(data->state.buffer, 1, readthisamountnow, +diff --git a/lib/telnet.c b/lib/telnet.c +index e43b423..4492514 100644 +--- a/lib/telnet.c ++++ b/lib/telnet.c +@@ -1429,7 +1429,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) + for(;;) { + if(obj_count == 1) { + /* read from user-supplied method */ +- code = (int)conn->fread_func(buf, 1, BUFSIZE - 1, conn->fread_in); ++ code = (int)conn->fread_func(buf, 1, buf_size, conn->fread_in); + if(code == CURL_READFUNC_ABORT) { + keepon = FALSE; + code = CURLE_READ_ERROR; +@@ -1502,7 +1502,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) + } + if(events.lNetworkEvents & FD_READ) { + /* read data from network */ +- code = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); ++ code = Curl_read(conn, sockfd, buf, data->set.buffer_size, &nread); + /* read would've blocked. Loop again */ + if(code == CURLE_AGAIN) + break; +@@ -1591,7 +1591,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) + default: /* read! */ + if(pfd[0].revents & POLLIN) { + /* read data from network */ +- code = Curl_read(conn, sockfd, buf, BUFSIZE - 1, &nread); ++ code = Curl_read(conn, sockfd, buf, data->set.buffer_size, &nread); + /* read would've blocked. Loop again */ + if(code == CURLE_AGAIN) + break; +@@ -1627,12 +1627,12 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done) + nread = 0; + if(poll_cnt == 2) { + if(pfd[1].revents & POLLIN) { /* read from in file */ +- nread = read(pfd[1].fd, buf, BUFSIZE - 1); ++ nread = read(pfd[1].fd, buf, data->set.buffer_size); + } + } + else { + /* read from user-supplied method */ +- nread = (int)conn->fread_func(buf, 1, BUFSIZE - 1, conn->fread_in); ++ nread = (int)conn->fread_func(buf, 1, data->set.buffer_size, conn->fread_in); + if(nread == CURL_READFUNC_ABORT) { + keepon = FALSE; + break; +diff --git a/lib/transfer.c b/lib/transfer.c +index b707f8a..77f0937 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -626,8 +626,6 @@ static CURLcode readwrite_data(struct SessionHandle *data, + excess = (size_t)(k->bytecount + nread - k->maxdownload); + if(excess > 0 && !k->ignorebody) { + if(conn->data->multi && Curl_multi_canPipeline(conn->data->multi)) { +- /* The 'excess' amount below can't be more than BUFSIZE which +- always will fit in a size_t */ + infof(data, + "Rewinding stream by : %zu" + " bytes on url %s (size = %" FORMAT_OFF_T +@@ -880,7 +878,7 @@ static CURLcode readwrite_upload(struct SessionHandle *data, + #endif + (data->set.crlf))) { + if(data->state.scratch == NULL) +- data->state.scratch = malloc(2*BUFSIZE); ++ data->state.scratch = malloc(2 * data->set.buffer_size); + if(data->state.scratch == NULL) { + failf (data, "Failed to alloc scratch buffer!"); + return CURLE_OUT_OF_MEMORY; +-- +2.17.2 + + +From a8725233e1af133dd1d89c89b30ef4396c3f2e5b Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 15:19:19 +0200 +Subject: [PATCH 15/18] sendf: remove use of BUFSIZE from debug data + conversions + +The buffer can have other sizes. + +Upstream-commit: 7ee52c25f35816968b86d32eaef70ab743a457d4 +Signed-off-by: Kamil Dudka +--- + lib/sendf.c | 51 ++++++++++++++++++++++++++------------------------- + 1 file changed, 26 insertions(+), 25 deletions(-) + +diff --git a/lib/sendf.c b/lib/sendf.c +index fb0e6e8..bad4683 100644 +--- a/lib/sendf.c ++++ b/lib/sendf.c +@@ -584,21 +584,19 @@ static int showit(struct SessionHandle *data, curl_infotype type, + { + static const char s_infotype[CURLINFO_END][3] = { + "* ", "< ", "> ", "{ ", "} ", "{ ", "} " }; ++ int rc = 0; + + #ifdef CURL_DOES_CONVERSIONS +- char buf[BUFSIZE+1]; ++ char *buf = NULL; + size_t conv_size = 0; + + switch(type) { + case CURLINFO_HEADER_OUT: +- /* assume output headers are ASCII */ +- /* copy the data into my buffer so the original is unchanged */ +- if(size > BUFSIZE) { +- size = BUFSIZE; /* truncate if necessary */ +- buf[BUFSIZE] = '\0'; +- } ++ buf = Curl_memdup(ptr, size); ++ if(!buf) ++ return 1; + conv_size = size; +- memcpy(buf, ptr, size); ++ + /* Special processing is needed for this block if it + * contains both headers and data (separated by CRLFCRLF). + * We want to convert just the headers, leaving the data as-is. +@@ -626,26 +624,29 @@ static int showit(struct SessionHandle *data, curl_infotype type, + #endif /* CURL_DOES_CONVERSIONS */ + + if(data->set.fdebug) +- return (*data->set.fdebug)(data, type, ptr, size, +- data->set.debugdata); +- +- switch(type) { +- case CURLINFO_TEXT: +- case CURLINFO_HEADER_OUT: +- case CURLINFO_HEADER_IN: +- fwrite(s_infotype[type], 2, 1, data->set.err); +- fwrite(ptr, size, 1, data->set.err); ++ rc = (*data->set.fdebug)(data, type, ptr, size, data->set.debugdata); ++ else { ++ switch(type) { ++ case CURLINFO_TEXT: ++ case CURLINFO_HEADER_OUT: ++ case CURLINFO_HEADER_IN: ++ fwrite(s_infotype[type], 2, 1, data->set.err); ++ fwrite(ptr, size, 1, data->set.err); + #ifdef CURL_DOES_CONVERSIONS +- if(size != conv_size) { +- /* we had untranslated data so we need an explicit newline */ +- fwrite("\n", 1, 1, data->set.err); +- } ++ if(size != conv_size) { ++ /* we had untranslated data so we need an explicit newline */ ++ fwrite("\n", 1, 1, data->set.err); ++ } + #endif +- break; +- default: /* nada */ +- break; ++ break; ++ default: /* nada */ ++ break; ++ } + } +- return 0; ++#ifdef CURL_DOES_CONVERSIONS ++ free(buf); ++#endif ++ return rc; + } + + int Curl_debug(struct SessionHandle *data, curl_infotype type, +-- +2.17.2 + + +From a600c050d0fcaa5bff272f47b9be0a653a4071c6 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 25 Apr 2017 15:31:14 +0200 +Subject: [PATCH 16/18] BUFSIZE: rename to READBUFFER_*, make separate + MASTERBUF_SIZE + +Upstream-commit: e3ed5cb380e615e91d99b09da9f0ead0eaf3e0b5 +Signed-off-by: Kamil Dudka +--- + lib/multi.c | 4 ++-- + lib/sendf.c | 2 +- + lib/url.c | 25 ++++++++++++++----------- + lib/urldata.h | 10 +++------- + 4 files changed, 20 insertions(+), 21 deletions(-) + +diff --git a/lib/multi.c b/lib/multi.c +index 3029fa6..39a0938 100644 +--- a/lib/multi.c ++++ b/lib/multi.c +@@ -1452,7 +1452,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, + + /* calculate upload rate-limitation timeout. */ + buffersize = (int)(data->set.buffer_size ? +- data->set.buffer_size : BUFSIZE); ++ data->set.buffer_size : MASTERBUF_SIZE); + timeout_ms = Curl_sleep_time(data->set.max_send_speed, + data->progress.ulspeed, buffersize); + Curl_expire(data, timeout_ms); +@@ -1468,7 +1468,7 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, + + /* Calculate download rate-limitation timeout. */ + buffersize = (int)(data->set.buffer_size ? +- data->set.buffer_size : BUFSIZE); ++ data->set.buffer_size : MASTERBUF_SIZE); + timeout_ms = Curl_sleep_time(data->set.max_recv_speed, + data->progress.dlspeed, buffersize); + Curl_expire(data, timeout_ms); +diff --git a/lib/sendf.c b/lib/sendf.c +index bad4683..95d1a51 100644 +--- a/lib/sendf.c ++++ b/lib/sendf.c +@@ -555,7 +555,7 @@ CURLcode Curl_read(struct connectdata *conn, /* connection data */ + } + /* If we come here, it means that there is no data to read from the buffer, + * so we read from the socket */ +- bytesfromsocket = CURLMIN(sizerequested, (size_t)data->set.buffer_size); ++ bytesfromsocket = CURLMIN(sizerequested, MASTERBUF_SIZE); + buffertofill = conn->master_buffer; + } + else { +diff --git a/lib/url.c b/lib/url.c +index b86243b..cb3f3c3 100644 +--- a/lib/url.c ++++ b/lib/url.c +@@ -242,6 +242,10 @@ static const struct Curl_handler * const protocols[] = { + (struct Curl_handler *) NULL + }; + ++#define READBUFFER_SIZE CURL_MAX_WRITE_SIZE ++#define READBUFFER_MAX CURL_MAX_READ_SIZE ++#define READBUFFER_MIN 1024 ++ + /* + * Dummy handler for undefined protocol schemes. + */ +@@ -577,7 +581,7 @@ CURLcode Curl_init_userdefined(struct UserDefined *set) + set->tcp_keepintvl = 60; + set->tcp_keepidle = 60; + +- set->buffer_size = BUFSIZE; ++ set->buffer_size = READBUFFER_SIZE; + + return res; + } +@@ -615,7 +619,7 @@ CURLcode Curl_open(struct SessionHandle **curl) + + /* We do some initial setup here, all those fields that can't be just 0 */ + +- data->state.buffer = malloc(BUFSIZE + 1); ++ data->state.buffer = malloc(READBUFFER_SIZE + 1); + if(!data->state.buffer) { + DEBUGF(fprintf(stderr, "Error: malloc of buffer failed\n")); + res = CURLE_OUT_OF_MEMORY; +@@ -1969,17 +1973,16 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, + */ + arg = va_arg(param, long); + +- if(arg > MAX_BUFSIZE) +- arg = MAX_BUFSIZE; /* huge internal default */ ++ if(arg > READBUFFER_MAX) ++ arg = READBUFFER_MAX; /* huge internal default */ + else if(arg < 1) +- arg = BUFSIZE; +- else if(arg < MIN_BUFSIZE) +- arg = BUFSIZE; ++ arg = READBUFFER_SIZE; ++ else if(arg < READBUFFER_MIN) ++ arg = READBUFFER_MIN; + + /* Resize only if larger than default buffer size. */ +- if(arg > BUFSIZE) { +- data->state.buffer = realloc(data->state.buffer, +- data->set.buffer_size + 1); ++ if(arg > READBUFFER_SIZE) { ++ data->state.buffer = realloc(data->state.buffer, arg + 1); + if(!data->state.buffer) { + DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n")); + result = CURLE_OUT_OF_MEMORY; +@@ -3537,7 +3540,7 @@ static struct connectdata *allocate_conn(struct SessionHandle *data) + if(data->multi && Curl_multi_canPipeline(data->multi) && + !conn->master_buffer) { + /* Allocate master_buffer to be used for pipelining */ +- conn->master_buffer = calloc(BUFSIZE, sizeof (char)); ++ conn->master_buffer = calloc(MASTERBUF_SIZE, sizeof (char)); + if(!conn->master_buffer) + goto error; + } +diff --git a/lib/urldata.h b/lib/urldata.h +index afe37c0..d10c784 100644 +--- a/lib/urldata.h ++++ b/lib/urldata.h +@@ -193,17 +193,13 @@ + #include + #endif /* HAVE_LIBSSH2_H */ + +-/* Download buffer size, keep it fairly big for speed reasons */ +-#undef BUFSIZE +-#define BUFSIZE CURL_MAX_WRITE_SIZE +-#undef MAX_BUFSIZE +-#define MAX_BUFSIZE CURL_MAX_READ_SIZE +-#define MIN_BUFSIZE 1024 +- + /* The upload buffer size, should not be smaller than CURL_MAX_WRITE_SIZE, as + it needs to hold a full buffer as could be sent in a write callback */ + #define UPLOAD_BUFSIZE CURL_MAX_WRITE_SIZE + ++/* The "master buffer" is for HTTP pipelining */ ++#define MASTERBUF_SIZE 16384 ++ + /* Initial size of the buffer to store headers in, it'll be enlarged in case + of need. */ + #define HEADERSIZE 256 +-- +2.17.2 + + +From 40c7b1ccca9fcf3b0ce261f098faebd58ed439ac Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Tue, 2 May 2017 08:32:04 +0200 +Subject: [PATCH 17/18] ssh: fix compiler warning from e40e9d7f0de + +Upstream-commit: eab6732fde094073480af5039b6fb495cbc3fb8a +Signed-off-by: Kamil Dudka +--- + lib/ssh.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/ssh.c b/lib/ssh.c +index 169ef1b..b1f136e 100644 +--- a/lib/ssh.c ++++ b/lib/ssh.c +@@ -1712,7 +1712,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn, bool *block) + do { + size_t readthisamountnow = + (data->state.resume_from - passed > data->set.buffer_size) ? +- data->set.buffer_size : ++ (size_t)data->set.buffer_size : + curlx_sotouz(data->state.resume_from - passed); + + size_t actuallyread = +-- +2.17.2 + + From 9f3810bae5fad685e848a39750863557e17a0163 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Thu, 8 Mar 2018 10:33:16 +0100 -Subject: [PATCH 7/7] readwrite: make sure excess reads don't go beyond buffer - end +Subject: [PATCH 18/18] readwrite: make sure excess reads don't go beyond + buffer end CVE-2018-1000122 Bug: https://curl.haxx.se/docs/adv_2018-b047.html @@ -644,7 +1640,7 @@ diff --git a/lib/transfer.c b/lib/transfer.c index dff6838..7ad6e3c 100644 --- a/lib/transfer.c +++ b/lib/transfer.c -@@ -738,10 +738,15 @@ static CURLcode readwrite_data(struct SessionHandle *data, +@@ -735,10 +735,15 @@ static CURLcode readwrite_data(struct SessionHandle *data, } /* if(! header and data to read ) */ diff --git a/SOURCES/0063-curl-7.29.0-CVE-2018-1000120.patch b/SOURCES/0063-curl-7.29.0-CVE-2018-1000120.patch index da3e4fe..4051f6e 100644 --- a/SOURCES/0063-curl-7.29.0-CVE-2018-1000120.patch +++ b/SOURCES/0063-curl-7.29.0-CVE-2018-1000120.patch @@ -75,7 +75,7 @@ index bcba6bb..fb3a716 100644 } cmd = aprintf( "%s%s%s", -@@ -3327,12 +3324,10 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, +@@ -3328,12 +3325,10 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, } /* get the "raw" path */ @@ -90,7 +90,7 @@ index bcba6bb..fb3a716 100644 ftpc->ctl_valid = FALSE; /* mark control connection as bad */ conn->bits.close = TRUE; /* mark for connection closure */ ftpc->prevpath = NULL; /* no path remembering */ -@@ -3643,7 +3638,7 @@ static CURLcode ftp_range(struct connectdata *conn) +@@ -3644,7 +3639,7 @@ static CURLcode ftp_range(struct connectdata *conn) } else { /* X-Y */ @@ -99,7 +99,7 @@ index bcba6bb..fb3a716 100644 data->state.resume_from = from; DEBUGF(infof(conn->data, "FTP RANGE from %" FORMAT_OFF_T " getting %" FORMAT_OFF_T " bytes\n", -@@ -4332,20 +4327,22 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) +@@ -4333,20 +4328,22 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) } slash_pos=strrchr(cur_pos, '/'); if(slash_pos || !*cur_pos) { @@ -129,7 +129,7 @@ index bcba6bb..fb3a716 100644 } else filename = cur_pos; /* this is a file name only */ -@@ -4377,18 +4374,15 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) +@@ -4378,18 +4375,15 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) /* we skip empty path components, like "x//y" since the FTP command CWD requires a parameter and a non-existent parameter a) doesn't work on many servers and b) has no effect on the others. */ @@ -155,7 +155,7 @@ index bcba6bb..fb3a716 100644 } } else { -@@ -4415,15 +4409,12 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) +@@ -4416,15 +4410,12 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) } /* switch */ if(filename && *filename) { @@ -176,7 +176,7 @@ index bcba6bb..fb3a716 100644 } } else -@@ -4441,15 +4432,17 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) +@@ -4442,15 +4433,17 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) if(ftpc->prevpath) { /* prevpath is "raw" so we convert the input path before we compare the strings */ @@ -295,7 +295,7 @@ diff --git a/lib/ftp.c b/lib/ftp.c index 9da5a24..0259a14 100644 --- a/lib/ftp.c +++ b/lib/ftp.c -@@ -3323,11 +3323,12 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, +@@ -3324,11 +3324,12 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, ftpc->known_filesize = -1; } @@ -356,7 +356,7 @@ index fb3a716..268efdd 100644 if(result) return result; } -@@ -3325,7 +3325,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, +@@ -3326,7 +3326,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status, if(!result) /* get the "raw" path */ @@ -365,7 +365,7 @@ index fb3a716..268efdd 100644 if(result) { /* We can limp along anyway (and should try to since we may already be in * the error path) */ -@@ -4337,7 +4337,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) +@@ -4338,7 +4338,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) slash_pos ? curlx_sztosi(slash_pos-cur_pos) : 1, &ftpc->dirs[0], NULL, @@ -374,7 +374,7 @@ index fb3a716..268efdd 100644 if(result) { freedirs(ftpc); return result; -@@ -4436,7 +4436,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) +@@ -4437,7 +4437,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn) size_t dlen; char *path; CURLcode result = diff --git a/SOURCES/0064-curl-7.29.0-CVE-2018-1000301.patch b/SOURCES/0064-curl-7.29.0-CVE-2018-1000301.patch index 9a06ee6..a4ad25e 100644 --- a/SOURCES/0064-curl-7.29.0-CVE-2018-1000301.patch +++ b/SOURCES/0064-curl-7.29.0-CVE-2018-1000301.patch @@ -1,8 +1,7 @@ From 5815730864a2010872840bae24797983e892eb90 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 24 Mar 2018 23:47:41 +0100 -Subject: [PATCH 1/2] http: restore buffer pointer when bad response-line is - parsed +Subject: [PATCH] http: restore buffer pointer when bad response-line is parsed ... leaving the k->str could lead to buffer over-reads later on. @@ -23,7 +22,7 @@ diff --git a/lib/http.c b/lib/http.c index 841f6cc..dc10f5f 100644 --- a/lib/http.c +++ b/lib/http.c -@@ -2789,6 +2789,8 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, +@@ -2791,6 +2791,8 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, { CURLcode result; struct SingleRequest *k = &data->req; @@ -32,7 +31,7 @@ index 841f6cc..dc10f5f 100644 /* header line within buffer loop */ do { -@@ -2853,7 +2855,9 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, +@@ -2855,7 +2857,9 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data, else { /* this was all we read so it's all a bad header */ k->badheader = HEADER_ALLBAD; diff --git a/SOURCES/0068-curl-7.29.0-CVE-2018-14618.patch b/SOURCES/0068-curl-7.29.0-CVE-2018-14618.patch new file mode 100644 index 0000000..be657c4 --- /dev/null +++ b/SOURCES/0068-curl-7.29.0-CVE-2018-14618.patch @@ -0,0 +1,93 @@ +From 3bae605ce08375120f34761e5a4364253276ec88 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sat, 4 Nov 2017 16:42:21 +0100 +Subject: [PATCH 1/2] ntlm: avoid malloc(0) for zero length passwords + +It triggers an assert() when built with memdebug since malloc(0) may +return NULL *or* a valid pointer. + +Detected by OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4054 + +Assisted-by: Max Dymond +Closes #2054 + +Upstream-commit: 685ef130575cdcf63fe9547757d88a49a40ef281 +Signed-off-by: Kamil Dudka +--- + lib/curl_ntlm_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c +index 8f3c00d..459f6f9 100644 +--- a/lib/curl_ntlm_core.c ++++ b/lib/curl_ntlm_core.c +@@ -385,7 +385,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data, + unsigned char *ntbuffer /* 21 bytes */) + { + size_t len = strlen(password); +- unsigned char *pw = malloc(len * 2); ++ unsigned char *pw = len ? malloc(len * 2) : strdup(""); + CURLcode result; + if(!pw) + return CURLE_OUT_OF_MEMORY; +-- +2.17.1 + + +From 4c20ad72a35f44c31241a916ccf9a789a01d5ab8 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 13 Aug 2018 10:35:52 +0200 +Subject: [PATCH 2/2] Curl_ntlm_core_mk_nt_hash: return error on too long + password + +... since it would cause an integer overflow if longer than (max size_t +/ 2). + +This is CVE-2018-14618 + +Bug: https://curl.haxx.se/docs/CVE-2018-14618.html +Closes #2756 +Reported-by: Zhaoyang Wu + +Upstream-commit: 57d299a499155d4b327e341c6024e293b0418243 +Signed-off-by: Kamil Dudka +--- + lib/curl_ntlm_core.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c +index 459f6f9..1b6551f 100644 +--- a/lib/curl_ntlm_core.c ++++ b/lib/curl_ntlm_core.c +@@ -128,6 +128,15 @@ static void setup_des_key(const unsigned char *key_56, + + #else /* defined(USE_SSLEAY) */ + ++#ifndef SIZE_T_MAX ++/* some limits.h headers have this defined, some don't */ ++#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4) ++#define SIZE_T_MAX 18446744073709551615U ++#else ++#define SIZE_T_MAX 4294967295U ++#endif ++#endif ++ + /* + * Turns a 56 bit key into the 64 bit, odd parity key. Used by GnuTLS and NSS. + */ +@@ -385,8 +394,11 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data, + unsigned char *ntbuffer /* 21 bytes */) + { + size_t len = strlen(password); +- unsigned char *pw = len ? malloc(len * 2) : strdup(""); ++ unsigned char *pw; + CURLcode result; ++ if(len > SIZE_T_MAX/2) /* avoid integer overflow */ ++ return CURLE_OUT_OF_MEMORY; ++ pw = len ? malloc(len * 2) : strdup(""); + if(!pw) + return CURLE_OUT_OF_MEMORY; + +-- +2.17.1 + diff --git a/SOURCES/0069-curl-7.29.0-file-limit-rate.patch b/SOURCES/0069-curl-7.29.0-file-limit-rate.patch new file mode 100644 index 0000000..ecf68a3 --- /dev/null +++ b/SOURCES/0069-curl-7.29.0-file-limit-rate.patch @@ -0,0 +1,90 @@ +From 4d5f2c162fe8b0a05f05c7f03573381c11ec2958 Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sun, 22 Dec 2013 23:36:11 +0100 +Subject: [PATCH 1/2] FILE: don't wait due to CURLOPT_MAX_RECV_SPEED_LARGE + +The FILE:// code doesn't support this option - and it doesn't make sense +to support it as long as it works as it does since then it'd only block +even longer. + +But: setting CURLOPT_MAX_RECV_SPEED_LARGE would make the transfer first +get done and then libcurl would wait until the average speed would get +low enough. This happened because the transfer happens completely in the +DO state for FILE:// but then it would still unconditionally continue in +to the PERFORM state where the speed check is made. + +Starting now, the code will skip from DO_DONE to DONE immediately if no +socket is set to be recv()ed or send()ed to. + +Bug: http://curl.haxx.se/bug/view.cgi?id=1312 +Reported-by: Mohammad AlSaleh + +Upstream-commit: 2715d7f948c8eb7cd3cba38f3dff6d4148e7cfaf +Signed-off-by: Kamil Dudka +--- + lib/multi.c | 8 +++++++- + 1 file changed, 7 insertions(+), 1 deletion(-) + +diff --git a/lib/multi.c b/lib/multi.c +index 39a0938..f27a18f 100644 +--- a/lib/multi.c ++++ b/lib/multi.c +@@ -1398,7 +1398,13 @@ static CURLMcode multi_runsingle(struct Curl_multi *multi, + moveHandleFromSendToRecvPipeline(data, easy->easy_conn); + /* Check if we can move pending requests to send pipe */ + checkPendPipeline(easy->easy_conn); +- multistate(easy, CURLM_STATE_WAITPERFORM); ++ /* Only perform the transfer if there's a good socket to work with. ++ Having both BAD is a signal to skip immediately to DONE */ ++ if((easy->easy_conn->sockfd != CURL_SOCKET_BAD) || ++ (easy->easy_conn->writesockfd != CURL_SOCKET_BAD)) ++ multistate(easy, CURLM_STATE_WAITPERFORM); ++ else ++ multistate(easy, CURLM_STATE_DONE); + result = CURLM_CALL_MULTI_PERFORM; + break; + +-- +2.17.2 + + +From 876a1e81ff44157bbd5e48ca5e120f4266aefc9e Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Sun, 22 Dec 2013 23:45:10 +0100 +Subject: [PATCH 2/2] docs: mention CURLOPT_MAX_RECV/SEND_SPEED_LARGE don't + work for FILE:// + +Upstream-commit: f718415bc7914f4c238c88d8f76b22ddf4d470c9 +Signed-off-by: Kamil Dudka +--- + docs/libcurl/curl_easy_setopt.3 | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3 +index 226e0ca..d720b95 100644 +--- a/docs/libcurl/curl_easy_setopt.3 ++++ b/docs/libcurl/curl_easy_setopt.3 +@@ -2053,12 +2053,18 @@ it too slow and abort. + Pass a curl_off_t as parameter. If an upload exceeds this speed (counted in + bytes per second) on cumulative average during the transfer, the transfer will + pause to keep the average rate less than or equal to the parameter value. +-Defaults to unlimited speed. (Added in 7.15.5) ++Defaults to unlimited speed. ++ ++This option doesn't affect transfer speeds done with FILE:// URLs. (Added in ++ 7.15.5) + .IP CURLOPT_MAX_RECV_SPEED_LARGE + Pass a curl_off_t as parameter. If a download exceeds this speed (counted in + bytes per second) on cumulative average during the transfer, the transfer will + pause to keep the average rate less than or equal to the parameter +-value. Defaults to unlimited speed. (Added in 7.15.5) ++value. Defaults to unlimited speed. ++ ++This option doesn't affect transfer speeds done with FILE:// URLs. (Added in ++7.15.5) + .IP CURLOPT_MAXCONNECTS + Pass a long. The set number will be the persistent connection cache size. The + set amount will be the maximum amount of simultaneously open connections that +-- +2.17.2 + diff --git a/SPECS/curl.spec b/SPECS/curl.spec index 5bab6fa..98b2fea 100644 --- a/SPECS/curl.spec +++ b/SPECS/curl.spec @@ -1,7 +1,7 @@ Summary: A utility for getting files from remote servers (FTP, HTTP, and others) Name: curl Version: 7.29.0 -Release: 51%{?dist} +Release: 51%{?dist}.3 License: MIT Group: Applications/Internet Source: http://curl.haxx.se/download/%{name}-%{version}.tar.lzma @@ -202,6 +202,12 @@ Patch64: 0064-curl-7.29.0-CVE-2018-1000301.patch # make curl --speed-limit work with TFTP (#1584750) Patch65: 0065-curl-7.29.0-tftp-speed-limit.patch +# prevent curl --rate-limit from hanging on file URLs (#1281969) +Patch69: 0069-curl-7.29.0-file-limit-rate.patch + +# fix NTLM password overflow via integer overflow (CVE-2018-14618) +Patch68: 0068-curl-7.29.0-CVE-2018-14618.patch + # patch making libcurl multilib ready Patch101: 0101-curl-7.29.0-multilib.patch @@ -397,6 +403,8 @@ documentation of the library, too. %patch63 -p1 %patch64 -p1 %patch65 -p1 +%patch68 -p1 +%patch69 -p1 # regenerate Makefile.in files aclocal -I m4 @@ -512,6 +520,15 @@ rm -rf $RPM_BUILD_ROOT %{_datadir}/aclocal/libcurl.m4 %changelog +* Mon May 27 2019 Kamil Dudka - 7.29.0-51.el7_6.3 +- fix NTLM password overflow via integer overflow (CVE-2018-14618) + +* Mon May 20 2019 Kamil Dudka - 7.29.0-51.el7_6.2 +- prevent curl --rate-limit from crashing on https URLs (#1683292) + +* Mon May 13 2019 Kamil Dudka - 7.29.0-51.el7_6.1 +- prevent curl --rate-limit from hanging on file URLs (#1281969) + * Wed Aug 08 2018 Kamil Dudka - 7.29.0-51 - require a new enough version of nss-pem to avoid regression in yum (#1610998)