Blame SOURCES/0061-curl-7.29.0-CVE-2018-1000122.patch

f0f8d7
From 9f163418fabbe6219ab04cfe9bf81d2f33bd54d7 Mon Sep 17 00:00:00 2001
f0f8d7
From: Richy Kim <richy@fb.com>
f0f8d7
Date: Tue, 20 Dec 2016 05:48:15 -0500
f0f8d7
Subject: [PATCH 1/7] CURLOPT_BUFFERSIZE: support enlarging receive buffer
f0f8d7
f0f8d7
Replace use of fixed macro BUFSIZE to define the size of the receive
f0f8d7
buffer.  Reappropriate CURLOPT_BUFFERSIZE to include enlarging receive
f0f8d7
buffer size.  Upon setting, resize buffer if larger than the current
f0f8d7
default size up to a MAX_BUFSIZE (512KB). This can benefit protocols
f0f8d7
like SFTP.
f0f8d7
f0f8d7
Closes #1222
f0f8d7
f0f8d7
Upstream-commit: 6b7616690e5370c21e3a760321af6bf4edbabfb6
f0f8d7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
f0f8d7
---
f0f8d7
 docs/libcurl/curl_easy_setopt.3  | 12 ++++++------
f0f8d7
 docs/libcurl/symbols-in-versions |  1 +
f0f8d7
 include/curl/curl.h              |  5 +++++
f0f8d7
 lib/easy.c                       |  6 ++++++
f0f8d7
 lib/file.c                       |  2 +-
f0f8d7
 lib/ftp.c                        |  4 ++--
f0f8d7
 lib/http.c                       |  3 ++-
f0f8d7
 lib/telnet.c                     |  5 +++--
f0f8d7
 lib/url.c                        | 28 +++++++++++++++++++++++-----
f0f8d7
 lib/urldata.h                    |  5 ++++-
f0f8d7
 10 files changed, 53 insertions(+), 18 deletions(-)
f0f8d7
f0f8d7
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
f0f8d7
index cbebfba..17b632f 100644
f0f8d7
--- a/docs/libcurl/curl_easy_setopt.3
f0f8d7
+++ b/docs/libcurl/curl_easy_setopt.3
f0f8d7
@@ -938,12 +938,12 @@ to using the share interface instead! See \fICURLOPT_SHARE\fP and
f0f8d7
 .IP CURLOPT_BUFFERSIZE
f0f8d7
 Pass a long specifying your preferred size (in bytes) for the receive buffer
f0f8d7
 in libcurl.  The main point of this would be that the write callback gets
f0f8d7
-called more often and with smaller chunks. This is just treated as a request,
f0f8d7
-not an order. You cannot be guaranteed to actually get the given size. (Added
f0f8d7
-in 7.10)
f0f8d7
-
f0f8d7
-This size is by default set as big as possible (CURL_MAX_WRITE_SIZE), so it
f0f8d7
-only makes sense to use this option if you want it smaller.
f0f8d7
+called more often and with smaller chunks.  Secondly, for some protocols,
f0f8d7
+there's a benefit of having a larger buffer for performance.  This is just
f0f8d7
+treated as a request, not an order. You cannot be guaranteed to actually get
f0f8d7
+the given size.  This buffer size is by default \fICURL_MAX_WRITE_SIZE\fP
f0f8d7
+(16kB). The maximum buffer size allowed to set is \fICURL_MAX_READ_SIZE\fP
f0f8d7
+(512kB).  (Added in 7.10)
f0f8d7
 .IP CURLOPT_PORT
f0f8d7
 Pass a long specifying what remote port number to connect to, instead of the
f0f8d7
 one specified in the URL or the default port for the used protocol.
f0f8d7
diff --git a/docs/libcurl/symbols-in-versions b/docs/libcurl/symbols-in-versions
f0f8d7
index b0b6232..e2cce4c 100644
f0f8d7
--- a/docs/libcurl/symbols-in-versions
f0f8d7
+++ b/docs/libcurl/symbols-in-versions
f0f8d7
@@ -639,6 +639,7 @@ CURL_LOCK_TYPE_DNS              7.10          -           7.10.2
f0f8d7
 CURL_LOCK_TYPE_NONE             7.10          -           7.10.2
f0f8d7
 CURL_LOCK_TYPE_SSL_SESSION      7.10          -           7.10.2
f0f8d7
 CURL_MAX_HTTP_HEADER            7.19.7
f0f8d7
+CURL_MAX_READ_SIZE              7.53.0
f0f8d7
 CURL_MAX_WRITE_SIZE             7.9.7
f0f8d7
 CURL_NETRC_IGNORED              7.9.8
f0f8d7
 CURL_NETRC_OPTIONAL             7.9.8
f0f8d7
diff --git a/include/curl/curl.h b/include/curl/curl.h
f0f8d7
index 0375a64..8b639fa 100644
f0f8d7
--- a/include/curl/curl.h
f0f8d7
+++ b/include/curl/curl.h
f0f8d7
@@ -170,6 +170,11 @@ typedef int (*curl_progress_callback)(void *clientp,
f0f8d7
                                       double ultotal,
f0f8d7
                                       double ulnow);
f0f8d7
 
f0f8d7
+#ifndef CURL_MAX_READ_SIZE
f0f8d7
+  /* The maximum receive buffer size configurable via CURLOPT_BUFFERSIZE. */
f0f8d7
+#define CURL_MAX_READ_SIZE 524288
f0f8d7
+#endif
f0f8d7
+
f0f8d7
 #ifndef CURL_MAX_WRITE_SIZE
f0f8d7
   /* Tests have proven that 20K is a very bad buffer size for uploads on
f0f8d7
      Windows, while 16K for some odd reason performed a lot better.
f0f8d7
diff --git a/lib/easy.c b/lib/easy.c
f0f8d7
index 0e9ba18..5d4d5ae 100644
f0f8d7
--- a/lib/easy.c
f0f8d7
+++ b/lib/easy.c
f0f8d7
@@ -563,6 +563,11 @@ CURL *curl_easy_duphandle(CURL *incurl)
f0f8d7
    * get setup on-demand in the code, as that would probably decrease
f0f8d7
    * the likeliness of us forgetting to init a buffer here in the future.
f0f8d7
    */
f0f8d7
+  outcurl->set.buffer_size = data->set.buffer_size;
f0f8d7
+  outcurl->state.buffer = malloc(CURL_BUFSIZE(outcurl->set.buffer_size) + 1);
f0f8d7
+  if(!outcurl->state.buffer)
f0f8d7
+    goto fail;
f0f8d7
+
f0f8d7
   outcurl->state.headerbuff = malloc(HEADERSIZE);
f0f8d7
   if(!outcurl->state.headerbuff)
f0f8d7
     goto fail;
f0f8d7
@@ -633,6 +638,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
f0f8d7
   if(outcurl) {
f0f8d7
     curl_slist_free_all(outcurl->change.cookielist);
f0f8d7
     outcurl->change.cookielist = NULL;
f0f8d7
+    Curl_safefree(outcurl->state.buffer);
f0f8d7
     Curl_safefree(outcurl->state.headerbuff);
f0f8d7
     Curl_safefree(outcurl->change.url);
f0f8d7
     Curl_safefree(outcurl->change.referer);
f0f8d7
diff --git a/lib/file.c b/lib/file.c
f0f8d7
index 038bf42..1ad4758 100644
f0f8d7
--- a/lib/file.c
f0f8d7
+++ b/lib/file.c
f0f8d7
@@ -473,7 +473,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
f0f8d7
      date. */
f0f8d7
   if(data->set.opt_no_body && data->set.include_header && fstated) {
f0f8d7
     CURLcode result;
f0f8d7
-    snprintf(buf, sizeof(data->state.buffer),
f0f8d7
+    snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
f0f8d7
              "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
f0f8d7
     result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
f0f8d7
     if(result)
f0f8d7
diff --git a/lib/ftp.c b/lib/ftp.c
f0f8d7
index a9826ce..730b695 100644
f0f8d7
--- a/lib/ftp.c
f0f8d7
+++ b/lib/ftp.c
f0f8d7
@@ -2136,7 +2136,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
f0f8d7
         /* we have a time, reformat it */
f0f8d7
         time_t secs=time(NULL);
f0f8d7
         /* using the good old yacc/bison yuck */
f0f8d7
-        snprintf(buf, sizeof(conn->data->state.buffer),
f0f8d7
+        snprintf(buf, CURL_BUFSIZE(conn->data->set.buffer_size),
f0f8d7
                  "%04d%02d%02d %02d:%02d:%02d GMT",
f0f8d7
                  year, month, day, hour, minute, second);
f0f8d7
         /* now, convert this into a time() value: */
f0f8d7
@@ -2347,7 +2347,7 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
f0f8d7
   if(instate == FTP_SIZE) {
f0f8d7
 #ifdef CURL_FTP_HTTPSTYLE_HEAD
f0f8d7
     if(-1 != filesize) {
f0f8d7
-      snprintf(buf, sizeof(data->state.buffer),
f0f8d7
+      snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
f0f8d7
                "Content-Length: %" FORMAT_OFF_T "\r\n", filesize);
f0f8d7
       result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
f0f8d7
       if(result)
f0f8d7
diff --git a/lib/http.c b/lib/http.c
f0f8d7
index 1487fb2..f4368c4 100644
f0f8d7
--- a/lib/http.c
f0f8d7
+++ b/lib/http.c
f0f8d7
@@ -247,7 +247,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
f0f8d7
     pwd = conn->passwd;
f0f8d7
   }
f0f8d7
 
f0f8d7
-  snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
f0f8d7
+  snprintf(data->state.buffer, CURL_BUFSIZE(data->set.buffer_size),
f0f8d7
+           "%s:%s", user, pwd);
f0f8d7
 
f0f8d7
   error = Curl_base64_encode(data,
f0f8d7
                              data->state.buffer, strlen(data->state.buffer),
f0f8d7
diff --git a/lib/telnet.c b/lib/telnet.c
f0f8d7
index 77d8b7b..89452dd 100644
f0f8d7
--- a/lib/telnet.c
f0f8d7
+++ b/lib/telnet.c
f0f8d7
@@ -1421,6 +1421,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
f0f8d7
 
f0f8d7
   /* Keep on listening and act on events */
f0f8d7
   while(keepon) {
f0f8d7
+    const size_t buf_size = CURL_BUFSIZE(data->set.buffer_size);
f0f8d7
     waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
f0f8d7
     switch(waitret) {
f0f8d7
     case WAIT_TIMEOUT:
f0f8d7
@@ -1455,7 +1456,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
f0f8d7
           if(!readfile_read)
f0f8d7
             break;
f0f8d7
 
f0f8d7
-          if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
f0f8d7
+          if(!ReadFile(stdin_handle, buf, buf_size,
f0f8d7
                        &readfile_read, NULL)) {
f0f8d7
             keepon = FALSE;
f0f8d7
             code = CURLE_READ_ERROR;
f0f8d7
@@ -1474,7 +1475,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
f0f8d7
 
f0f8d7
     case WAIT_OBJECT_0 + 1:
f0f8d7
     {
f0f8d7
-      if(!ReadFile(stdin_handle, buf, sizeof(data->state.buffer),
f0f8d7
+      if(!ReadFile(stdin_handle, buf, buf_size,
f0f8d7
                    &readfile_read, NULL)) {
f0f8d7
         keepon = FALSE;
f0f8d7
         code = CURLE_READ_ERROR;
f0f8d7
diff --git a/lib/url.c b/lib/url.c
f0f8d7
index 89958a7..32e7e2e 100644
f0f8d7
--- a/lib/url.c
f0f8d7
+++ b/lib/url.c
f0f8d7
@@ -441,6 +441,7 @@ CURLcode Curl_close(struct SessionHandle *data)
f0f8d7
   }
f0f8d7
   data->change.url = NULL;
f0f8d7
 
f0f8d7
+  Curl_safefree(data->state.buffer);
f0f8d7
   Curl_safefree(data->state.headerbuff);
f0f8d7
 
f0f8d7
   Curl_flush_cookies(data, 1);
f0f8d7
@@ -612,6 +613,12 @@ CURLcode Curl_open(struct SessionHandle **curl)
f0f8d7
 
f0f8d7
   /* We do some initial setup here, all those fields that can't be just 0 */
f0f8d7
 
f0f8d7
+  data->state.buffer = malloc(BUFSIZE + 1);
f0f8d7
+  if(!data->state.buffer) {
f0f8d7
+    DEBUGF(fprintf(stderr, "Error: malloc of buffer failed\n"));
f0f8d7
+    res = CURLE_OUT_OF_MEMORY;
f0f8d7
+  }
f0f8d7
+
f0f8d7
   data->state.headerbuff = malloc(HEADERSIZE);
f0f8d7
   if(!data->state.headerbuff) {
f0f8d7
     DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n"));
f0f8d7
@@ -642,8 +649,8 @@ CURLcode Curl_open(struct SessionHandle **curl)
f0f8d7
 
f0f8d7
   if(res) {
f0f8d7
     Curl_resolver_cleanup(data->state.resolver);
f0f8d7
-    if(data->state.headerbuff)
f0f8d7
-      free(data->state.headerbuff);
f0f8d7
+    free(data->state.buffer);
f0f8d7
+    free(data->state.headerbuff);
f0f8d7
     Curl_freeset(data);
f0f8d7
     free(data);
f0f8d7
     data = NULL;
f0f8d7
@@ -1960,9 +1967,20 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
f0f8d7
      */
f0f8d7
     data->set.buffer_size = va_arg(param, long);
f0f8d7
 
f0f8d7
-    if((data->set.buffer_size> (BUFSIZE -1 )) ||
f0f8d7
-       (data->set.buffer_size < 1))
f0f8d7
-      data->set.buffer_size = 0; /* huge internal default */
f0f8d7
+    if(data->set.buffer_size > MAX_BUFSIZE)
f0f8d7
+      data->set.buffer_size = MAX_BUFSIZE; /* huge internal default */
f0f8d7
+    else if(data->set.buffer_size < 1)
f0f8d7
+      data->set.buffer_size = BUFSIZE;
f0f8d7
+
f0f8d7
+    /* Resize only if larger than default buffer size. */
f0f8d7
+    if(data->set.buffer_size > BUFSIZE) {
f0f8d7
+      data->state.buffer = realloc(data->state.buffer,
f0f8d7
+                                   data->set.buffer_size + 1);
f0f8d7
+      if(!data->state.buffer) {
f0f8d7
+        DEBUGF(fprintf(stderr, "Error: realloc of buffer failed\n"));
f0f8d7
+        result = CURLE_OUT_OF_MEMORY;
f0f8d7
+      }
f0f8d7
+    }
f0f8d7
 
f0f8d7
     break;
f0f8d7
 
f0f8d7
diff --git a/lib/urldata.h b/lib/urldata.h
f0f8d7
index 7431825..a7807cf 100644
f0f8d7
--- a/lib/urldata.h
f0f8d7
+++ b/lib/urldata.h
f0f8d7
@@ -196,6 +196,9 @@
f0f8d7
 /* Download buffer size, keep it fairly big for speed reasons */
f0f8d7
 #undef BUFSIZE
f0f8d7
 #define BUFSIZE CURL_MAX_WRITE_SIZE
f0f8d7
+#undef MAX_BUFSIZE
f0f8d7
+#define MAX_BUFSIZE CURL_MAX_READ_SIZE
f0f8d7
+#define CURL_BUFSIZE(x) ((x)?(x):(BUFSIZE))
f0f8d7
 
f0f8d7
 /* Initial size of the buffer to store headers in, it'll be enlarged in case
f0f8d7
    of need. */
f0f8d7
@@ -1174,7 +1177,7 @@ struct UrlState {
f0f8d7
   char *headerbuff; /* allocated buffer to store headers in */
f0f8d7
   size_t headersize;   /* size of the allocation */
f0f8d7
 
f0f8d7
-  char buffer[BUFSIZE+1]; /* download buffer */
f0f8d7
+  char *buffer; /* download buffer */
f0f8d7
   char uploadbuffer[BUFSIZE+1]; /* upload buffer */
f0f8d7
   curl_off_t current_speed;  /* the ProgressShow() funcion sets this,
f0f8d7
                                 bytes / second */
f0f8d7
-- 
f0f8d7
2.14.3
f0f8d7
f0f8d7
f0f8d7
From f175a713c964d351012baaf8c78c1b468cc6aba0 Mon Sep 17 00:00:00 2001
f0f8d7
From: Daniel Stenberg <daniel@haxx.se>
f0f8d7
Date: Mon, 24 Apr 2017 15:33:57 +0200
f0f8d7
Subject: [PATCH 2/7] http: use private user:password output buffer
f0f8d7
f0f8d7
Don't clobber the receive buffer.
f0f8d7
f0f8d7
Upstream-commit: 94460878cc634b590a7282e3fe60ceafb62d141a
f0f8d7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
f0f8d7
---
f0f8d7
 lib/http.c | 32 +++++++++++++++++++-------------
f0f8d7
 1 file changed, 19 insertions(+), 13 deletions(-)
f0f8d7
f0f8d7
diff --git a/lib/http.c b/lib/http.c
f0f8d7
index f4368c4..12e7dc3 100644
f0f8d7
--- a/lib/http.c
f0f8d7
+++ b/lib/http.c
f0f8d7
@@ -234,7 +234,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
f0f8d7
   char **userp;
f0f8d7
   const char *user;
f0f8d7
   const char *pwd;
f0f8d7
-  CURLcode error;
f0f8d7
+  CURLcode result;
f0f8d7
+  char *out;
f0f8d7
 
f0f8d7
   if(proxy) {
f0f8d7
     userp = &conn->allocptr.proxyuserpwd;
f0f8d7
@@ -247,27 +248,32 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
f0f8d7
     pwd = conn->passwd;
f0f8d7
   }
f0f8d7
 
f0f8d7
-  snprintf(data->state.buffer, CURL_BUFSIZE(data->set.buffer_size),
f0f8d7
-           "%s:%s", user, pwd);
f0f8d7
+  out = aprintf("%s:%s", user, pwd);
f0f8d7
+  if(!out)
f0f8d7
+    return CURLE_OUT_OF_MEMORY;
f0f8d7
 
f0f8d7
-  error = Curl_base64_encode(data,
f0f8d7
-                             data->state.buffer, strlen(data->state.buffer),
f0f8d7
-                             &authorization, &size);
f0f8d7
-  if(error)
f0f8d7
-    return error;
f0f8d7
+  result = Curl_base64_encode(data, out, strlen(out), &authorization, &size);
f0f8d7
+  if(result)
f0f8d7
+    goto fail;
f0f8d7
 
f0f8d7
-  if(!authorization)
f0f8d7
-    return CURLE_REMOTE_ACCESS_DENIED;
f0f8d7
+  if(!authorization) {
f0f8d7
+    result = CURLE_REMOTE_ACCESS_DENIED;
f0f8d7
+    goto fail;
f0f8d7
+  }
f0f8d7
 
f0f8d7
   Curl_safefree(*userp);
f0f8d7
   *userp = aprintf("%sAuthorization: Basic %s\r\n",
f0f8d7
                    proxy?"Proxy-":"",
f0f8d7
                    authorization);
f0f8d7
   free(authorization);
f0f8d7
-  if(!*userp)
f0f8d7
-    return CURLE_OUT_OF_MEMORY;
f0f8d7
+  if(!*userp) {
f0f8d7
+    result = CURLE_OUT_OF_MEMORY;
f0f8d7
+    goto fail;
f0f8d7
+  }
f0f8d7
 
f0f8d7
-  return CURLE_OK;
f0f8d7
+  fail:
f0f8d7
+  free(out);
f0f8d7
+  return result;
f0f8d7
 }
f0f8d7
 
f0f8d7
 /* pickoneauth() selects the most favourable authentication method from the
f0f8d7
-- 
f0f8d7
2.14.3
f0f8d7
f0f8d7
f0f8d7
From 6ff175806c338223a2a9a69f6ae8ae2b91dc2b56 Mon Sep 17 00:00:00 2001
f0f8d7
From: Daniel Stenberg <daniel@haxx.se>
f0f8d7
Date: Mon, 24 Apr 2017 16:05:46 +0200
f0f8d7
Subject: [PATCH 3/7] ftp: use private buffer for temp storage, not receive
f0f8d7
 buffer
f0f8d7
f0f8d7
Upstream-commit: 349789e645a306a6ee467ef90a57f6cc306ca92e
f0f8d7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
f0f8d7
---
f0f8d7
 lib/ftp.c | 22 ++++++++++++----------
f0f8d7
 1 file changed, 12 insertions(+), 10 deletions(-)
f0f8d7
f0f8d7
diff --git a/lib/ftp.c b/lib/ftp.c
f0f8d7
index 730b695..10a21ce 100644
f0f8d7
--- a/lib/ftp.c
f0f8d7
+++ b/lib/ftp.c
f0f8d7
@@ -2130,17 +2130,17 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
f0f8d7
       /* we got a time. Format should be: "YYYYMMDDHHMMSS[.sss]" where the
f0f8d7
          last .sss part is optional and means fractions of a second */
f0f8d7
       int year, month, day, hour, minute, second;
f0f8d7
-      char *buf = data->state.buffer;
f0f8d7
-      if(6 == sscanf(buf+4, "%04d%02d%02d%02d%02d%02d",
f0f8d7
+      if(6 == sscanf(&data->state.buffer[4], "%04d%02d%02d%02d%02d%02d",
f0f8d7
                      &year, &month, &day, &hour, &minute, &second)) {
f0f8d7
         /* we have a time, reformat it */
f0f8d7
+        char timebuf[24];
f0f8d7
         time_t secs=time(NULL);
f0f8d7
-        /* using the good old yacc/bison yuck */
f0f8d7
-        snprintf(buf, CURL_BUFSIZE(conn->data->set.buffer_size),
f0f8d7
+
f0f8d7
+        snprintf(timebuf, sizeof(timebuf),
f0f8d7
                  "%04d%02d%02d %02d:%02d:%02d GMT",
f0f8d7
                  year, month, day, hour, minute, second);
f0f8d7
         /* now, convert this into a time() value: */
f0f8d7
-        data->info.filetime = (long)curl_getdate(buf, &secs;;
f0f8d7
+        data->info.filetime = (long)curl_getdate(timebuf, &secs;;
f0f8d7
       }
f0f8d7
 
f0f8d7
 #ifdef CURL_FTP_HTTPSTYLE_HEAD
f0f8d7
@@ -2151,6 +2151,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
f0f8d7
          ftpc->file &&
f0f8d7
          data->set.get_filetime &&
f0f8d7
          (data->info.filetime>=0) ) {
f0f8d7
+        char headerbuf[128];
f0f8d7
         time_t filetime = (time_t)data->info.filetime;
f0f8d7
         struct tm buffer;
f0f8d7
         const struct tm *tm = &buffer;
f0f8d7
@@ -2160,7 +2161,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
f0f8d7
           return result;
f0f8d7
 
f0f8d7
         /* format: "Tue, 15 Nov 1994 12:45:26" */
f0f8d7
-        snprintf(buf, BUFSIZE-1,
f0f8d7
+        snprintf(headerbuf, sizeof(headerbuf),
f0f8d7
                  "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
f0f8d7
                  Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
f0f8d7
                  tm->tm_mday,
f0f8d7
@@ -2169,7 +2170,7 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
f0f8d7
                  tm->tm_hour,
f0f8d7
                  tm->tm_min,
f0f8d7
                  tm->tm_sec);
f0f8d7
-        result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
f0f8d7
+        result = Curl_client_write(conn, CLIENTWRITE_BOTH, headerbuf, 0);
f0f8d7
         if(result)
f0f8d7
           return result;
f0f8d7
       } /* end of a ridiculous amount of conditionals */
f0f8d7
@@ -2347,9 +2348,10 @@ static CURLcode ftp_state_size_resp(struct connectdata *conn,
f0f8d7
   if(instate == FTP_SIZE) {
f0f8d7
 #ifdef CURL_FTP_HTTPSTYLE_HEAD
f0f8d7
     if(-1 != filesize) {
f0f8d7
-      snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
f0f8d7
+      char clbuf[128];
f0f8d7
+      snprintf(clbuf, sizeof(clbuf),
f0f8d7
                "Content-Length: %" FORMAT_OFF_T "\r\n", filesize);
f0f8d7
-      result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
f0f8d7
+      result = Curl_client_write(conn, CLIENTWRITE_BOTH, clbuf, 0);
f0f8d7
       if(result)
f0f8d7
         return result;
f0f8d7
     }
f0f8d7
@@ -2450,7 +2452,6 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
f0f8d7
   CURLcode result = CURLE_OK;
f0f8d7
   struct SessionHandle *data = conn->data;
f0f8d7
   struct FTP *ftp = data->state.proto.ftp;
f0f8d7
-  char *buf = data->state.buffer;
f0f8d7
 
f0f8d7
   if((ftpcode == 150) || (ftpcode == 125)) {
f0f8d7
 
f0f8d7
@@ -2494,6 +2495,7 @@ static CURLcode ftp_state_get_resp(struct connectdata *conn,
f0f8d7
        *
f0f8d7
        * Example D above makes this parsing a little tricky */
f0f8d7
       char *bytes;
f0f8d7
+      char *buf = data->state.buffer;
f0f8d7
       bytes=strstr(buf, " bytes");
f0f8d7
       if(bytes--) {
f0f8d7
         long in=(long)(bytes-buf);
f0f8d7
-- 
f0f8d7
2.14.3
f0f8d7
f0f8d7
f0f8d7
From b67324919089fc4f9bb7a38a6a31174883a4bc24 Mon Sep 17 00:00:00 2001
f0f8d7
From: Daniel Stenberg <daniel@haxx.se>
f0f8d7
Date: Tue, 25 Apr 2017 00:09:22 +0200
f0f8d7
Subject: [PATCH 4/7] CURLOPT_BUFFERSIZE: 1024 bytes is now the minimum size
f0f8d7
f0f8d7
The buffer is needed to receive FTP, HTTP CONNECT responses etc so
f0f8d7
already at this size things risk breaking and smaller is certainly not
f0f8d7
wise.
f0f8d7
f0f8d7
Upstream-commit: c2ddc12d6086b522703c8b80a72ab791680f1a28
f0f8d7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
f0f8d7
---
f0f8d7
 lib/url.c     | 15 +++++++++------
f0f8d7
 lib/urldata.h |  1 +
f0f8d7
 2 files changed, 10 insertions(+), 6 deletions(-)
f0f8d7
f0f8d7
diff --git a/lib/url.c b/lib/url.c
f0f8d7
index 32e7e2e..f87dca4 100644
f0f8d7
--- a/lib/url.c
f0f8d7
+++ b/lib/url.c
f0f8d7
@@ -1965,15 +1965,17 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
f0f8d7
      * The application kindly asks for a differently sized receive buffer.
f0f8d7
      * If it seems reasonable, we'll use it.
f0f8d7
      */
f0f8d7
-    data->set.buffer_size = va_arg(param, long);
f0f8d7
+    arg = va_arg(param, long);
f0f8d7
 
f0f8d7
-    if(data->set.buffer_size > MAX_BUFSIZE)
f0f8d7
-      data->set.buffer_size = MAX_BUFSIZE; /* huge internal default */
f0f8d7
-    else if(data->set.buffer_size < 1)
f0f8d7
-      data->set.buffer_size = BUFSIZE;
f0f8d7
+    if(arg > MAX_BUFSIZE)
f0f8d7
+      arg = MAX_BUFSIZE; /* huge internal default */
f0f8d7
+    else if(arg < 1)
f0f8d7
+      arg = BUFSIZE;
f0f8d7
+    else if(arg < MIN_BUFSIZE)
f0f8d7
+      arg = BUFSIZE;
f0f8d7
 
f0f8d7
     /* Resize only if larger than default buffer size. */
f0f8d7
-    if(data->set.buffer_size > BUFSIZE) {
f0f8d7
+    if(arg > BUFSIZE) {
f0f8d7
       data->state.buffer = realloc(data->state.buffer,
f0f8d7
                                    data->set.buffer_size + 1);
f0f8d7
       if(!data->state.buffer) {
f0f8d7
@@ -1981,6 +1983,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
f0f8d7
         result = CURLE_OUT_OF_MEMORY;
f0f8d7
       }
f0f8d7
     }
f0f8d7
+    data->set.buffer_size = arg;
f0f8d7
 
f0f8d7
     break;
f0f8d7
 
f0f8d7
diff --git a/lib/urldata.h b/lib/urldata.h
f0f8d7
index a7807cf..cd96e8f 100644
f0f8d7
--- a/lib/urldata.h
f0f8d7
+++ b/lib/urldata.h
f0f8d7
@@ -198,6 +198,7 @@
f0f8d7
 #define BUFSIZE CURL_MAX_WRITE_SIZE
f0f8d7
 #undef MAX_BUFSIZE
f0f8d7
 #define MAX_BUFSIZE CURL_MAX_READ_SIZE
f0f8d7
+#define MIN_BUFSIZE 1024
f0f8d7
 #define CURL_BUFSIZE(x) ((x)?(x):(BUFSIZE))
f0f8d7
 
f0f8d7
 /* Initial size of the buffer to store headers in, it'll be enlarged in case
f0f8d7
-- 
f0f8d7
2.14.3
f0f8d7
f0f8d7
f0f8d7
From 9798012315c087168c5a4a1dc56eacfe82c69626 Mon Sep 17 00:00:00 2001
f0f8d7
From: Daniel Stenberg <daniel@haxx.se>
f0f8d7
Date: Tue, 25 Apr 2017 00:15:28 +0200
f0f8d7
Subject: [PATCH 5/7] file: use private buffer for C-L output
f0f8d7
f0f8d7
... instead of clobbering the download buffer.
f0f8d7
f0f8d7
Upstream-commit: 7c312f84ea930d89c0f0f774b50032c4f9ae30e4
f0f8d7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
f0f8d7
---
f0f8d7
 lib/file.c | 7 ++++---
f0f8d7
 1 file changed, 4 insertions(+), 3 deletions(-)
f0f8d7
f0f8d7
diff --git a/lib/file.c b/lib/file.c
f0f8d7
index 1ad4758..b6bf18e 100644
f0f8d7
--- a/lib/file.c
f0f8d7
+++ b/lib/file.c
f0f8d7
@@ -473,9 +473,10 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
f0f8d7
      date. */
f0f8d7
   if(data->set.opt_no_body && data->set.include_header && fstated) {
f0f8d7
     CURLcode result;
f0f8d7
-    snprintf(buf, CURL_BUFSIZE(data->set.buffer_size),
f0f8d7
+    char header[80];
f0f8d7
+    snprintf(header, sizeof(header),
f0f8d7
              "Content-Length: %" FORMAT_OFF_T "\r\n", expected_size);
f0f8d7
-    result = Curl_client_write(conn, CLIENTWRITE_BOTH, buf, 0);
f0f8d7
+    result = Curl_client_write(conn, CLIENTWRITE_BOTH, header, 0);
f0f8d7
     if(result)
f0f8d7
       return result;
f0f8d7
 
f0f8d7
@@ -493,7 +494,7 @@ static CURLcode file_do(struct connectdata *conn, bool *done)
f0f8d7
         return result;
f0f8d7
 
f0f8d7
       /* format: "Tue, 15 Nov 1994 12:45:26 GMT" */
f0f8d7
-      snprintf(buf, BUFSIZE-1,
f0f8d7
+      snprintf(header, sizeof(header),
f0f8d7
                "Last-Modified: %s, %02d %s %4d %02d:%02d:%02d GMT\r\n",
f0f8d7
                Curl_wkday[tm->tm_wday?tm->tm_wday-1:6],
f0f8d7
                tm->tm_mday,
f0f8d7
-- 
f0f8d7
2.14.3
f0f8d7
f0f8d7
f0f8d7
From f4868e737e9f8d719cb9897506da2c7f92dfd87d Mon Sep 17 00:00:00 2001
f0f8d7
From: Daniel Stenberg <daniel@haxx.se>
f0f8d7
Date: Tue, 25 Apr 2017 00:16:10 +0200
f0f8d7
Subject: [PATCH 6/7] buffer_size: make sure it always has the correct size
f0f8d7
f0f8d7
Removes the need for CURL_BUFSIZE
f0f8d7
f0f8d7
Upstream-commit: f535f4f5fc6cbdce1aec5a3481cec37369dca468
f0f8d7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
f0f8d7
---
f0f8d7
 lib/easy.c    | 2 +-
f0f8d7
 lib/telnet.c  | 2 +-
f0f8d7
 lib/url.c     | 2 ++
f0f8d7
 lib/urldata.h | 1 -
f0f8d7
 4 files changed, 4 insertions(+), 3 deletions(-)
f0f8d7
f0f8d7
diff --git a/lib/easy.c b/lib/easy.c
f0f8d7
index 5d4d5ae..9cad5f1 100644
f0f8d7
--- a/lib/easy.c
f0f8d7
+++ b/lib/easy.c
f0f8d7
@@ -564,7 +564,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
f0f8d7
    * the likeliness of us forgetting to init a buffer here in the future.
f0f8d7
    */
f0f8d7
   outcurl->set.buffer_size = data->set.buffer_size;
f0f8d7
-  outcurl->state.buffer = malloc(CURL_BUFSIZE(outcurl->set.buffer_size) + 1);
f0f8d7
+  outcurl->state.buffer = malloc(outcurl->set.buffer_size + 1);
f0f8d7
   if(!outcurl->state.buffer)
f0f8d7
     goto fail;
f0f8d7
 
f0f8d7
diff --git a/lib/telnet.c b/lib/telnet.c
f0f8d7
index 89452dd..e43b423 100644
f0f8d7
--- a/lib/telnet.c
f0f8d7
+++ b/lib/telnet.c
f0f8d7
@@ -1421,7 +1421,7 @@ static CURLcode telnet_do(struct connectdata *conn, bool *done)
f0f8d7
 
f0f8d7
   /* Keep on listening and act on events */
f0f8d7
   while(keepon) {
f0f8d7
-    const size_t buf_size = CURL_BUFSIZE(data->set.buffer_size);
f0f8d7
+    const size_t buf_size = (DWORD)data->set.buffer_size;
f0f8d7
     waitret = WaitForMultipleObjects(obj_count, objs, FALSE, wait_timeout);
f0f8d7
     switch(waitret) {
f0f8d7
     case WAIT_TIMEOUT:
f0f8d7
diff --git a/lib/url.c b/lib/url.c
f0f8d7
index f87dca4..81de7c2 100644
f0f8d7
--- a/lib/url.c
f0f8d7
+++ b/lib/url.c
f0f8d7
@@ -577,6 +577,8 @@ CURLcode Curl_init_userdefined(struct UserDefined *set)
f0f8d7
   set->tcp_keepintvl = 60;
f0f8d7
   set->tcp_keepidle = 60;
f0f8d7
 
f0f8d7
+  set->buffer_size = BUFSIZE;
f0f8d7
+
f0f8d7
   return res;
f0f8d7
 }
f0f8d7
 
f0f8d7
diff --git a/lib/urldata.h b/lib/urldata.h
f0f8d7
index cd96e8f..fbe69c2 100644
f0f8d7
--- a/lib/urldata.h
f0f8d7
+++ b/lib/urldata.h
f0f8d7
@@ -199,7 +199,6 @@
f0f8d7
 #undef MAX_BUFSIZE
f0f8d7
 #define MAX_BUFSIZE CURL_MAX_READ_SIZE
f0f8d7
 #define MIN_BUFSIZE 1024
f0f8d7
-#define CURL_BUFSIZE(x) ((x)?(x):(BUFSIZE))
f0f8d7
 
f0f8d7
 /* Initial size of the buffer to store headers in, it'll be enlarged in case
f0f8d7
    of need. */
f0f8d7
-- 
f0f8d7
2.14.3
f0f8d7
f0f8d7
f0f8d7
From 9f3810bae5fad685e848a39750863557e17a0163 Mon Sep 17 00:00:00 2001
f0f8d7
From: Daniel Stenberg <daniel@haxx.se>
f0f8d7
Date: Thu, 8 Mar 2018 10:33:16 +0100
f0f8d7
Subject: [PATCH 7/7] readwrite: make sure excess reads don't go beyond buffer
f0f8d7
 end
f0f8d7
f0f8d7
CVE-2018-1000122
f0f8d7
Bug: https://curl.haxx.se/docs/adv_2018-b047.html
f0f8d7
f0f8d7
Detected by OSS-fuzz
f0f8d7
f0f8d7
Upstream-commit: d52dc4760f6d9ca1937eefa2093058a952465128
f0f8d7
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
f0f8d7
---
f0f8d7
 lib/transfer.c | 9 +++++++--
f0f8d7
 1 file changed, 7 insertions(+), 2 deletions(-)
f0f8d7
f0f8d7
diff --git a/lib/transfer.c b/lib/transfer.c
f0f8d7
index dff6838..7ad6e3c 100644
f0f8d7
--- a/lib/transfer.c
f0f8d7
+++ b/lib/transfer.c
f0f8d7
@@ -738,10 +738,15 @@ static CURLcode readwrite_data(struct SessionHandle *data,
f0f8d7
 
f0f8d7
     } /* if(! header and data to read ) */
f0f8d7
 
f0f8d7
-    if(conn->handler->readwrite &&
f0f8d7
-       (excess > 0 && !conn->bits.stream_was_rewound)) {
f0f8d7
+    if(conn->handler->readwrite && excess && !conn->bits.stream_was_rewound) {
f0f8d7
       /* Parse the excess data */
f0f8d7
       k->str += nread;
f0f8d7
+
f0f8d7
+      if(&k->str[excess] > &k->buf[data->set.buffer_size]) {
f0f8d7
+        /* the excess amount was too excessive(!), make sure
f0f8d7
+           it doesn't read out of buffer */
f0f8d7
+        excess = &k->buf[data->set.buffer_size] - k->str;
f0f8d7
+      }
f0f8d7
       nread = (ssize_t)excess;
f0f8d7
 
f0f8d7
       result = conn->handler->readwrite(data, conn, &nread, &readmore);
f0f8d7
-- 
f0f8d7
2.14.3
f0f8d7