summaryrefslogtreecommitdiffstats
path: root/meta/recipes-support/curl/curl/CVE-2023-28322.patch
blob: 9351a2c286a0be9ccbc9cf9feb54c5b22b6c96da (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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
CVE: CVE-2023-28322
Upstream-Status: Backport [ import patch from ubuntu curl_7.68.0-1ubuntu2.20
upstream https://github.com/curl/curl/commit/7815647d6582c0a4900be2e1de ]
Signed-off-by: Lee Chee Yang <chee.yang.lee@intel.com>

Backport of:

From 7815647d6582c0a4900be2e1de6c5e61272c496b Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 25 Apr 2023 08:28:01 +0200
Subject: [PATCH] lib: unify the upload/method handling

By making sure we set state.upload based on the set.method value and not
independently as set.upload, we reduce confusion and mixup risks, both
internally and externally.

Closes #11017
---
 lib/curl_rtmp.c    | 4 ++--
 lib/file.c         | 4 ++--
 lib/ftp.c          | 8 ++++----
 lib/http.c         | 4 ++--
 lib/imap.c         | 6 +++---
 lib/rtsp.c         | 4 ++--
 lib/setopt.c       | 6 ++----
 lib/smb.c          | 6 +++---
 lib/smtp.c         | 4 ++--
 lib/tftp.c         | 8 ++++----
 lib/transfer.c     | 4 ++--
 lib/urldata.h      | 2 +-
 lib/vssh/libssh.c  | 6 +++---
 lib/vssh/libssh2.c | 6 +++---
 lib/vssh/wolfssh.c | 2 +-
 15 files changed, 36 insertions(+), 38 deletions(-)

--- a/lib/curl_rtmp.c
+++ b/lib/curl_rtmp.c
@@ -213,7 +213,7 @@ static CURLcode rtmp_connect(struct conn
   /* We have to know if it's a write before we send the
    * connect request packet
    */
-  if(conn->data->set.upload)
+  if(conn->data->state.upload)
     r->Link.protocol |= RTMP_FEATURE_WRITE;
 
   /* For plain streams, use the buffer toggle trick to keep data flowing */
@@ -245,7 +245,7 @@ static CURLcode rtmp_do(struct connectda
   if(!RTMP_ConnectStream(r, 0))
     return CURLE_FAILED_INIT;
 
-  if(conn->data->set.upload) {
+  if(conn->data->state.upload) {
     Curl_pgrsSetUploadSize(data, data->state.infilesize);
     Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
   }
--- a/lib/file.c
+++ b/lib/file.c
@@ -198,7 +198,7 @@ static CURLcode file_connect(struct conn
   file->freepath = real_path; /* free this when done */
 
   file->fd = fd;
-  if(!data->set.upload && (fd == -1)) {
+  if(!data->state.upload && (fd == -1)) {
     failf(data, "Couldn't open file %s", data->state.up.path);
     file_done(conn, CURLE_FILE_COULDNT_READ_FILE, FALSE);
     return CURLE_FILE_COULDNT_READ_FILE;
@@ -390,7 +390,7 @@ static CURLcode file_do(struct connectda
 
   Curl_pgrsStartNow(data);
 
-  if(data->set.upload)
+  if(data->state.upload)
     return file_upload(conn);
 
   file = conn->data->req.protop;
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1371,7 +1371,7 @@ static CURLcode ftp_state_prepare_transf
                 data->set.str[STRING_CUSTOMREQUEST]:
                 (data->set.ftp_list_only?"NLST":"LIST"));
       }
-      else if(data->set.upload) {
+      else if(data->state.upload) {
         PPSENDF(&conn->proto.ftpc.pp, "PRET STOR %s", conn->proto.ftpc.file);
       }
       else {
@@ -3303,7 +3303,7 @@ static CURLcode ftp_done(struct connectd
     /* the response code from the transfer showed an error already so no
        use checking further */
     ;
-  else if(data->set.upload) {
+  else if(data->state.upload) {
     if((-1 != data->state.infilesize) &&
        (data->state.infilesize != data->req.writebytecount) &&
        !data->set.crlf &&
@@ -3570,7 +3570,7 @@ static CURLcode ftp_do_more(struct conne
                            connected back to us */
       }
     }
-    else if(data->set.upload) {
+    else if(data->state.upload) {
       result = ftp_nb_type(conn, data->set.prefer_ascii, FTP_STOR_TYPE);
       if(result)
         return result;
@@ -4209,7 +4209,7 @@ CURLcode ftp_parse_url_path(struct conne
     ftpc->file = NULL; /* instead of point to a zero byte,
                             we make it a NULL pointer */
 
-  if(data->set.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) {
+  if(data->state.upload && !ftpc->file && (ftp->transfer == FTPTRANSFER_BODY)) {
     /* We need a file name when uploading. Return error! */
     failf(data, "Uploading to a URL without a file name!");
     free(rawPath);
--- a/lib/http.c
+++ b/lib/http.c
@@ -2080,7 +2080,7 @@ CURLcode Curl_http(struct connectdata *c
   }
 
   if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
-     data->set.upload) {
+     data->state.upload) {
     httpreq = HTTPREQ_PUT;
   }
 
@@ -2261,7 +2261,7 @@ CURLcode Curl_http(struct connectdata *c
     if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
        (((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) &&
          http->postsize < 0) ||
-        ((data->set.upload || httpreq == HTTPREQ_POST) &&
+        ((data->state.upload || httpreq == HTTPREQ_POST) &&
          data->state.infilesize == -1))) {
       if(conn->bits.authneg)
         /* don't enable chunked during auth neg */
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -1469,11 +1469,11 @@ static CURLcode imap_done(struct connect
     result = status;         /* use the already set error code */
   }
   else if(!data->set.connect_only && !imap->custom &&
-          (imap->uid || imap->mindex || data->set.upload ||
+          (imap->uid || imap->mindex || data->state.upload ||
           data->set.mimepost.kind != MIMEKIND_NONE)) {
     /* Handle responses after FETCH or APPEND transfer has finished */
 
-    if(!data->set.upload && data->set.mimepost.kind == MIMEKIND_NONE)
+    if(!data->state.upload && data->set.mimepost.kind == MIMEKIND_NONE)
       state(conn, IMAP_FETCH_FINAL);
     else {
       /* End the APPEND command first by sending an empty line */
@@ -1539,7 +1539,7 @@ static CURLcode imap_perform(struct conn
     selected = TRUE;
 
   /* Start the first command in the DO phase */
-  if(conn->data->set.upload || data->set.mimepost.kind != MIMEKIND_NONE)
+  if(conn->data->state.upload || data->set.mimepost.kind != MIMEKIND_NONE)
     /* APPEND can be executed directly */
     result = imap_perform_append(conn);
   else if(imap->custom && (selected || !imap->mailbox))
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -499,7 +499,7 @@ static CURLcode rtsp_do(struct connectda
      rtspreq == RTSPREQ_SET_PARAMETER ||
      rtspreq == RTSPREQ_GET_PARAMETER) {
 
-    if(data->set.upload) {
+    if(data->state.upload) {
       putsize = data->state.infilesize;
       data->set.httpreq = HTTPREQ_PUT;
 
@@ -518,7 +518,7 @@ static CURLcode rtsp_do(struct connectda
         result =
           Curl_add_bufferf(&req_buffer,
                            "Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
-                           (data->set.upload ? putsize : postsize));
+                           (data->state.upload ? putsize : postsize));
         if(result)
           return result;
       }
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -258,8 +258,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *
      * We want to sent data to the remote host. If this is HTTP, that equals
      * using the PUT request.
      */
-    data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE;
-    if(data->set.upload) {
+    arg = va_arg(param, long);
+    if(arg) {
       /* If this is HTTP, PUT is what's needed to "upload" */
       data->set.httpreq = HTTPREQ_PUT;
       data->set.opt_no_body = FALSE; /* this is implied */
@@ -486,7 +486,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *
     }
     else
       data->set.httpreq = HTTPREQ_GET;
-    data->set.upload = FALSE;
     break;
 
   case CURLOPT_COPYPOSTFIELDS:
@@ -797,7 +796,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *
      */
     if(va_arg(param, long)) {
       data->set.httpreq = HTTPREQ_GET;
-      data->set.upload = FALSE; /* switch off upload */
       data->set.opt_no_body = FALSE; /* this is implied */
     }
     break;
--- a/lib/smb.c
+++ b/lib/smb.c
@@ -516,7 +516,7 @@ static CURLcode smb_send_open(struct con
   byte_count = strlen(req->path);
   msg.name_length = smb_swap16((unsigned short)byte_count);
   msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL);
-  if(conn->data->set.upload) {
+  if(conn->data->state.upload) {
     msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE);
     msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF);
   }
@@ -792,7 +792,7 @@ static CURLcode smb_request_state(struct
     smb_m = (const struct smb_nt_create_response*) msg;
     req->fid = smb_swap16(smb_m->fid);
     conn->data->req.offset = 0;
-    if(conn->data->set.upload) {
+    if(conn->data->state.upload) {
       conn->data->req.size = conn->data->state.infilesize;
       Curl_pgrsSetUploadSize(conn->data, conn->data->req.size);
       next_state = SMB_UPLOAD;
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -1210,7 +1210,7 @@ static CURLcode smtp_done(struct connect
     result = status;         /* use the already set error code */
   }
   else if(!data->set.connect_only && data->set.mail_rcpt &&
-          (data->set.upload || data->set.mimepost.kind)) {
+          (data->state.upload || data->set.mimepost.kind)) {
     /* Calculate the EOB taking into account any terminating CRLF from the
        previous line of the email or the CRLF of the DATA command when there
        is "no mail data". RFC-5321, sect. 4.1.1.4.
@@ -1297,7 +1297,7 @@ static CURLcode smtp_perform(struct conn
   smtp->eob = 2;
 
   /* Start the first command in the DO phase */
-  if((data->set.upload || data->set.mimepost.kind) && data->set.mail_rcpt)
+  if((data->state.upload || data->set.mimepost.kind) && data->set.mail_rcpt)
     /* MAIL transfer */
     result = smtp_perform_mail(conn);
   else
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -390,7 +390,7 @@ static CURLcode tftp_parse_option_ack(tf
 
       /* tsize should be ignored on upload: Who cares about the size of the
          remote file? */
-      if(!data->set.upload) {
+      if(!data->state.upload) {
         if(!tsize) {
           failf(data, "invalid tsize -:%s:- value in OACK packet", value);
           return CURLE_TFTP_ILLEGAL;
@@ -470,7 +470,7 @@ static CURLcode tftp_send_first(tftp_sta
       return result;
     }
 
-    if(data->set.upload) {
+    if(data->state.upload) {
       /* If we are uploading, send an WRQ */
       setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
       state->conn->data->req.upload_fromhere =
@@ -505,7 +505,7 @@ static CURLcode tftp_send_first(tftp_sta
     if(!data->set.tftp_no_options) {
       char buf[64];
       /* add tsize option */
-      if(data->set.upload && (data->state.infilesize != -1))
+      if(data->state.upload && (data->state.infilesize != -1))
         msnprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
                   data->state.infilesize);
       else
@@ -559,7 +559,7 @@ static CURLcode tftp_send_first(tftp_sta
     break;
 
   case TFTP_EVENT_OACK:
-    if(data->set.upload) {
+    if(data->state.upload) {
       result = tftp_connect_for_tx(state, event);
     }
     else {
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1405,6 +1405,7 @@ void Curl_init_CONNECT(struct Curl_easy
 {
   data->state.fread_func = data->set.fread_func_set;
   data->state.in = data->set.in_set;
+  data->state.upload = (data->set.httpreq == HTTPREQ_PUT);
 }
 
 /*
@@ -1816,7 +1817,7 @@ CURLcode Curl_retry_request(struct conne
 
   /* if we're talking upload, we can't do the checks below, unless the protocol
      is HTTP as when uploading over HTTP we will still get a response */
-  if(data->set.upload &&
+  if(data->state.upload &&
      !(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)))
     return CURLE_OK;
 
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1427,6 +1427,7 @@ struct UrlState {
   BIT(stream_depends_e); /* set or don't set the Exclusive bit */
   BIT(previouslypending); /* this transfer WAS in the multi->pending queue */
   BIT(cookie_engine);
+  BIT(upload);         /* upload request */
 };
 
 
@@ -1762,7 +1763,6 @@ struct UserDefined {
   BIT(http_auto_referer); /* set "correct" referer when following
                              location: */
   BIT(opt_no_body);    /* as set with CURLOPT_NOBODY */
-  BIT(upload);         /* upload request */
   BIT(verbose);        /* output verbosity */
   BIT(krb);            /* Kerberos connection requested */
   BIT(reuse_forbid);   /* forbidden to be reused, close after use */
--- a/lib/vssh/libssh.c
+++ b/lib/vssh/libssh.c
@@ -1076,7 +1076,7 @@ static CURLcode myssh_statemach_act(stru
     }
 
     case SSH_SFTP_TRANS_INIT:
-      if(data->set.upload)
+      if(data->state.upload)
         state(conn, SSH_SFTP_UPLOAD_INIT);
       else {
         if(protop->path[strlen(protop->path)-1] == '/')
@@ -1686,7 +1686,7 @@ static CURLcode myssh_statemach_act(stru
       /* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */
       ssh_set_blocking(sshc->ssh_session, 1);
 
-      if(data->set.upload) {
+      if(data->state.upload) {
         if(data->state.infilesize < 0) {
           failf(data, "SCP requires a known file size for upload");
           sshc->actualcode = CURLE_UPLOAD_FAILED;
@@ -1787,7 +1787,7 @@ static CURLcode myssh_statemach_act(stru
         break;
       }
     case SSH_SCP_DONE:
-      if(data->set.upload)
+      if(data->state.upload)
         state(conn, SSH_SCP_SEND_EOF);
       else
         state(conn, SSH_SCP_CHANNEL_FREE);
--- a/lib/vssh/libssh2.c
+++ b/lib/vssh/libssh2.c
@@ -1664,7 +1664,7 @@ static CURLcode ssh_statemach_act(struct
     }
 
     case SSH_SFTP_TRANS_INIT:
-      if(data->set.upload)
+      if(data->state.upload)
         state(conn, SSH_SFTP_UPLOAD_INIT);
       else {
         if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')
@@ -2366,7 +2366,7 @@ static CURLcode ssh_statemach_act(struct
         break;
       }
 
-      if(data->set.upload) {
+      if(data->state.upload) {
         if(data->state.infilesize < 0) {
           failf(data, "SCP requires a known file size for upload");
           sshc->actualcode = CURLE_UPLOAD_FAILED;
@@ -2504,7 +2504,7 @@ static CURLcode ssh_statemach_act(struct
     break;
 
     case SSH_SCP_DONE:
-      if(data->set.upload)
+      if(data->state.upload)
         state(conn, SSH_SCP_SEND_EOF);
       else
         state(conn, SSH_SCP_CHANNEL_FREE);