summaryrefslogtreecommitdiff
path: root/poky/meta/recipes-support/curl/curl/CVE-2023-27534.patch
blob: aeeffd5feab52e9d5961376c4ceb5ad40132c79c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
From 4e2b52b5f7a3bf50a0f1494155717b02cc1df6d6 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 9 Mar 2023 16:22:11 +0100
Subject: [PATCH] curl_path: create the new path with dynbuf

CVE: CVE-2023-27534
Upstream-Status: Backport [https://github.com/curl/curl/commit/4e2b52b5f7a3bf50a0f1494155717b02cc1df6d6]

Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
---
 lib/curl_path.c | 71 ++++++++++++++++++++++++-------------------------
 1 file changed, 35 insertions(+), 36 deletions(-)

diff --git a/lib/curl_path.c b/lib/curl_path.c
index f429634..e17db4b 100644
--- a/lib/curl_path.c
+++ b/lib/curl_path.c
@@ -30,6 +30,8 @@
 #include "escape.h"
 #include "memdebug.h"
 
+#define MAX_SSHPATH_LEN 100000 /* arbitrary */
+
 /* figure out the path to work with in this particular request */
 CURLcode Curl_getworkingpath(struct connectdata *conn,
                              char *homedir,  /* when SFTP is used */
@@ -37,60 +39,57 @@ CURLcode Curl_getworkingpath(struct connectdata *conn,
                                              real path to work with */
 {
   struct Curl_easy *data = conn->data;
-  char *real_path = NULL;
   char *working_path;
   size_t working_path_len;
+  struct dynbuf npath;
   CURLcode result =
     Curl_urldecode(data, data->state.up.path, 0, &working_path,
                    &working_path_len, FALSE);
   if(result)
     return result;
 
+  /* new path to switch to in case we need to */
+  Curl_dyn_init(&npath, MAX_SSHPATH_LEN);
+
   /* Check for /~/, indicating relative to the user's home directory */
-  if(conn->handler->protocol & CURLPROTO_SCP) {
-    real_path = malloc(working_path_len + 1);
-    if(real_path == NULL) {
+  if((data->conn->handler->protocol & CURLPROTO_SCP) &&
+     (working_path_len > 3) && (!memcmp(working_path, "/~/", 3))) {
+    /* It is referenced to the home directory, so strip the leading '/~/' */
+    if(Curl_dyn_addn(&npath, &working_path[3], working_path_len - 3)) {
       free(working_path);
       return CURLE_OUT_OF_MEMORY;
     }
-    if((working_path_len > 3) && (!memcmp(working_path, "/~/", 3)))
-      /* It is referenced to the home directory, so strip the leading '/~/' */
-      memcpy(real_path, working_path + 3, working_path_len - 2);
-    else
-      memcpy(real_path, working_path, 1 + working_path_len);
   }
-  else if(conn->handler->protocol & CURLPROTO_SFTP) {
-    if((working_path_len > 1) && (working_path[1] == '~')) {
-      size_t homelen = strlen(homedir);
-      real_path = malloc(homelen + working_path_len + 1);
-      if(real_path == NULL) {
-        free(working_path);
-        return CURLE_OUT_OF_MEMORY;
-      }
-      /* It is referenced to the home directory, so strip the
-         leading '/' */
-      memcpy(real_path, homedir, homelen);
-      real_path[homelen] = '/';
-      real_path[homelen + 1] = '\0';
-      if(working_path_len > 3) {
-        memcpy(real_path + homelen + 1, working_path + 3,
-               1 + working_path_len -3);
-      }
+  else if((data->conn->handler->protocol & CURLPROTO_SFTP) &&
+          (working_path_len > 2) && !memcmp(working_path, "/~/", 3)) {
+    size_t len;
+    const char *p;
+    int copyfrom = 3;
+    if(Curl_dyn_add(&npath, homedir)) {
+      free(working_path);
+      return CURLE_OUT_OF_MEMORY;
     }
-    else {
-      real_path = malloc(working_path_len + 1);
-      if(real_path == NULL) {
-        free(working_path);
-        return CURLE_OUT_OF_MEMORY;
-      }
-      memcpy(real_path, working_path, 1 + working_path_len);
+    /* Copy a separating '/' if homedir does not end with one */
+    len = Curl_dyn_len(&npath);
+    p = Curl_dyn_ptr(&npath);
+    if(len && (p[len-1] != '/'))
+      copyfrom = 2;
+
+    if(Curl_dyn_addn(&npath,
+                     &working_path[copyfrom], working_path_len - copyfrom)) {
+      free(working_path);
+      return CURLE_OUT_OF_MEMORY;
     }
   }
 
-  free(working_path);
+  if(Curl_dyn_len(&npath)) {
+    free(working_path);
 
-  /* store the pointer for the caller to receive */
-  *path = real_path;
+    /* store the pointer for the caller to receive */
+    *path = Curl_dyn_ptr(&npath);
+  }
+  else
+    *path = working_path;
 
   return CURLE_OK;
 }
-- 
2.25.1