Blame SOURCES/0018-curl-7.65.3-CVE-2019-5482.patch

3bb8f6
From 63f9837b4ccf600da79314e8667f91bda69988fc Mon Sep 17 00:00:00 2001
3bb8f6
From: Thomas Vegas <>
3bb8f6
Date: Sat, 31 Aug 2019 16:59:56 +0200
3bb8f6
Subject: [PATCH 1/2] tftp: return error when packet is too small for options
3bb8f6
3bb8f6
Upstream-commit: 82f3ba3806a34fe94dcf9e5c9b88deda6679ca1b
3bb8f6
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
3bb8f6
---
3bb8f6
 lib/tftp.c | 53 +++++++++++++++++++++++++++++++++--------------------
3bb8f6
 1 file changed, 33 insertions(+), 20 deletions(-)
3bb8f6
3bb8f6
diff --git a/lib/tftp.c b/lib/tftp.c
3bb8f6
index 289cda2..4532170 100644
3bb8f6
--- a/lib/tftp.c
3bb8f6
+++ b/lib/tftp.c
3bb8f6
@@ -404,13 +404,14 @@ static CURLcode tftp_parse_option_ack(tftp_state_data_t *state,
3bb8f6
   return CURLE_OK;
3bb8f6
 }
3bb8f6
 
3bb8f6
-static size_t tftp_option_add(tftp_state_data_t *state, size_t csize,
3bb8f6
-                              char *buf, const char *option)
3bb8f6
+static CURLcode tftp_option_add(tftp_state_data_t *state, size_t *csize,
3bb8f6
+                                char *buf, const char *option)
3bb8f6
 {
3bb8f6
-  if(( strlen(option) + csize + 1) > (size_t)state->blksize)
3bb8f6
-    return 0;
3bb8f6
+  if(( strlen(option) + *csize + 1) > (size_t)state->blksize)
3bb8f6
+    return CURLE_TFTP_ILLEGAL;
3bb8f6
   strcpy(buf, option);
3bb8f6
-  return strlen(option) + 1;
3bb8f6
+  *csize += strlen(option) + 1;
3bb8f6
+  return CURLE_OK;
3bb8f6
 }
3bb8f6
 
3bb8f6
 static CURLcode tftp_connect_for_tx(tftp_state_data_t *state,
3bb8f6
@@ -511,26 +512,38 @@ static CURLcode tftp_send_first(tftp_state_data_t *state, tftp_event_t event)
3bb8f6
       else
3bb8f6
         strcpy(buf, "0"); /* the destination is large enough */
3bb8f6
 
3bb8f6
-      sbytes += tftp_option_add(state, sbytes,
3bb8f6
-                                (char *)state->spacket.data + sbytes,
3bb8f6
-                                TFTP_OPTION_TSIZE);
3bb8f6
-      sbytes += tftp_option_add(state, sbytes,
3bb8f6
-                                (char *)state->spacket.data + sbytes, buf);
3bb8f6
+      result = tftp_option_add(state, &sbytes,
3bb8f6
+                               (char *)state->spacket.data + sbytes,
3bb8f6
+                               TFTP_OPTION_TSIZE);
3bb8f6
+      if(result == CURLE_OK)
3bb8f6
+        result = tftp_option_add(state, &sbytes,
3bb8f6
+                                 (char *)state->spacket.data + sbytes, buf);
3bb8f6
+
3bb8f6
       /* add blksize option */
3bb8f6
       snprintf(buf, sizeof(buf), "%d", state->requested_blksize);
3bb8f6
-      sbytes += tftp_option_add(state, sbytes,
3bb8f6
-                                (char *)state->spacket.data + sbytes,
3bb8f6
-                                TFTP_OPTION_BLKSIZE);
3bb8f6
-      sbytes += tftp_option_add(state, sbytes,
3bb8f6
-                                (char *)state->spacket.data + sbytes, buf);
3bb8f6
+      if(result == CURLE_OK)
3bb8f6
+        result = tftp_option_add(state, &sbytes,
3bb8f6
+                                 (char *)state->spacket.data + sbytes,
3bb8f6
+                                 TFTP_OPTION_BLKSIZE);
3bb8f6
+      if(result == CURLE_OK)
3bb8f6
+        result = tftp_option_add(state, &sbytes,
3bb8f6
+                                 (char *)state->spacket.data + sbytes, buf);
3bb8f6
 
3bb8f6
       /* add timeout option */
3bb8f6
       snprintf(buf, sizeof(buf), "%d", state->retry_time);
3bb8f6
-      sbytes += tftp_option_add(state, sbytes,
3bb8f6
-                                (char *)state->spacket.data + sbytes,
3bb8f6
-                                TFTP_OPTION_INTERVAL);
3bb8f6
-      sbytes += tftp_option_add(state, sbytes,
3bb8f6
-                                (char *)state->spacket.data + sbytes, buf);
3bb8f6
+      if(result == CURLE_OK)
3bb8f6
+        result = tftp_option_add(state, &sbytes,
3bb8f6
+                                 (char *)state->spacket.data + sbytes,
3bb8f6
+                                 TFTP_OPTION_INTERVAL);
3bb8f6
+      if(result == CURLE_OK)
3bb8f6
+        result = tftp_option_add(state, &sbytes,
3bb8f6
+                                 (char *)state->spacket.data + sbytes, buf);
3bb8f6
+
3bb8f6
+      if(result != CURLE_OK) {
3bb8f6
+        failf(data, "TFTP buffer too small for options");
3bb8f6
+        free(filename);
3bb8f6
+        return CURLE_TFTP_ILLEGAL;
3bb8f6
+      }
3bb8f6
     }
3bb8f6
 
3bb8f6
     /* the typecase for the 3rd argument is mostly for systems that do
3bb8f6
-- 
3bb8f6
2.20.1
3bb8f6
3bb8f6
3bb8f6
From b6b12a4cfe00c4850a1d6cee4cf267f00dee5987 Mon Sep 17 00:00:00 2001
3bb8f6
From: Thomas Vegas <>
3bb8f6
Date: Sat, 31 Aug 2019 17:30:51 +0200
3bb8f6
Subject: [PATCH 2/2] tftp: Alloc maximum blksize, and use default unless OACK
3bb8f6
 is received
3bb8f6
3bb8f6
Fixes potential buffer overflow from 'recvfrom()', should the server
3bb8f6
return an OACK without blksize.
3bb8f6
3bb8f6
Bug: https://curl.haxx.se/docs/CVE-2019-5482.html
3bb8f6
CVE-2019-5482
3bb8f6
3bb8f6
Upstream-commit: facb0e4662415b5f28163e853dc6742ac5fafb3d
3bb8f6
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
3bb8f6
---
3bb8f6
 lib/tftp.c | 12 +++++++++---
3bb8f6
 1 file changed, 9 insertions(+), 3 deletions(-)
3bb8f6
3bb8f6
diff --git a/lib/tftp.c b/lib/tftp.c
3bb8f6
index 4532170..5651b62 100644
3bb8f6
--- a/lib/tftp.c
3bb8f6
+++ b/lib/tftp.c
3bb8f6
@@ -982,6 +982,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
3bb8f6
 {
3bb8f6
   tftp_state_data_t *state;
3bb8f6
   int blksize;
3bb8f6
+  int need_blksize;
3bb8f6
 
3bb8f6
   blksize = TFTP_BLKSIZE_DEFAULT;
3bb8f6
 
3bb8f6
@@ -996,15 +997,20 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
3bb8f6
       return CURLE_TFTP_ILLEGAL;
3bb8f6
   }
3bb8f6
 
3bb8f6
+  need_blksize = blksize;
3bb8f6
+  /* default size is the fallback when no OACK is received */
3bb8f6
+  if(need_blksize < TFTP_BLKSIZE_DEFAULT)
3bb8f6
+    need_blksize = TFTP_BLKSIZE_DEFAULT;
3bb8f6
+
3bb8f6
   if(!state->rpacket.data) {
3bb8f6
-    state->rpacket.data = calloc(1, blksize + 2 + 2);
3bb8f6
+    state->rpacket.data = calloc(1, need_blksize + 2 + 2);
3bb8f6
 
3bb8f6
     if(!state->rpacket.data)
3bb8f6
       return CURLE_OUT_OF_MEMORY;
3bb8f6
   }
3bb8f6
 
3bb8f6
   if(!state->spacket.data) {
3bb8f6
-    state->spacket.data = calloc(1, blksize + 2 + 2);
3bb8f6
+    state->spacket.data = calloc(1, need_blksize + 2 + 2);
3bb8f6
 
3bb8f6
     if(!state->spacket.data)
3bb8f6
       return CURLE_OUT_OF_MEMORY;
3bb8f6
@@ -1018,7 +1024,7 @@ static CURLcode tftp_connect(struct connectdata *conn, bool *done)
3bb8f6
   state->sockfd = state->conn->sock[FIRSTSOCKET];
3bb8f6
   state->state = TFTP_STATE_START;
3bb8f6
   state->error = TFTP_ERR_NONE;
3bb8f6
-  state->blksize = blksize;
3bb8f6
+  state->blksize = TFTP_BLKSIZE_DEFAULT; /* Unless updated by OACK response */
3bb8f6
   state->requested_blksize = blksize;
3bb8f6
 
3bb8f6
   ((struct sockaddr *)&state->local_addr)->sa_family =
3bb8f6
-- 
3bb8f6
2.20.1
3bb8f6