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

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