summaryrefslogtreecommitdiffstats
path: root/meta/recipes-support/curl/curl/CVE-2023-28322-2.patch
blob: f2134dd1c357b75c0f75e2f09da24d1a8ba0ed42 (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
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
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

CVE: CVE-2023-28322
Upstream-Status: Backport [https://github.com/curl/curl/commit/7815647d6582c0a4900be2e1de]
Comments: Hunks refreshed
Signed-off-by: Bhabu Bindu <bhabu.bindu@kpit.com>
---
 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(-)

diff --git a/lib/curl_rtmp.c b/lib/curl_rtmp.c
index 2679a2cdc1afe..406fb42ac0f44 100644
--- a/lib/curl_rtmp.c
+++ b/lib/curl_rtmp.c
@@ -231,7 +231,7 @@ static CURLcode rtmp_connect(struct Curl_easy *data, bool *done)
   /* We have to know if it's a write before we send the
    * connect request packet
    */
-  if(data->set.upload)
+  if(data->state.upload)
     r->Link.protocol |= RTMP_FEATURE_WRITE;
 
   /* For plain streams, use the buffer toggle trick to keep data flowing */
@@ -263,7 +263,7 @@ static CURLcode rtmp_do(struct Curl_easy *data, bool *done)
   if(!RTMP_ConnectStream(r, 0))
     return CURLE_FAILED_INIT;
 
-  if(data->set.upload) {
+  if(data->state.upload) {
     Curl_pgrsSetUploadSize(data, data->state.infilesize);
     Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
   }
diff --git a/lib/file.c b/lib/file.c
index 51c5d07ce40ab..c751e8861a99b 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -240,7 +240,7 @@ static CURLcode file_connect(struct Curl_easy *data, bool *done)
   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(data, CURLE_FILE_COULDNT_READ_FILE, FALSE);
     return CURLE_FILE_COULDNT_READ_FILE;
@@ -422,7 +422,7 @@ static CURLcode file_do(struct Curl_easy *data, bool *done)
 
   Curl_pgrsStartNow(data);
 
-  if(data->set.upload)
+  if(data->state.upload)
     return file_upload(data);
 
   file = data->req.p.file;
diff --git a/lib/ftp.c b/lib/ftp.c
index f50d7baf622f8..4ff68cc454cbc 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1348,7 +1348,7 @@ static CURLcode ftp_state_prepare_transfer(struct Curl_easy *data)
                                data->set.str[STRING_CUSTOMREQUEST]?
                                data->set.str[STRING_CUSTOMREQUEST]:
                                (data->state.list_only?"NLST":"LIST"));
-      else if(data->set.upload)
+      else if(data->state.upload)
         result = Curl_pp_sendf(data, &ftpc->pp, "PRET STOR %s",
                                conn->proto.ftpc.file);
       else
@@ -3384,7 +3384,7 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
     /* 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 &&
@@ -3640,7 +3640,7 @@ static CURLcode ftp_do_more(struct Curl_easy *data, int *completep)
                            connected back to us */
       }
     }
-    else if(data->set.upload) {
+    else if(data->state.upload) {
       result = ftp_nb_type(data, conn, data->state.prefer_ascii,
                            FTP_STOR_TYPE);
       if(result)
@@ -4233,7 +4233,7 @@
     ftpc->file = NULL; /* instead of point to a zero byte,
                             we make it a NULL pointer */
 
-  if(data->set.upload && !ftpc->file && (ftp->transfer == PPTRANSFER_BODY)) {
+  if(data->state.upload && !ftpc->file && (ftp->transfer == PPTRANSFER_BODY)) {
     /* We need a file name when uploading. Return error! */
     failf(data, "Uploading to a URL without a file name!");
     free(rawPath);
diff --git a/lib/http.c b/lib/http.c
index 80e43f6f361e8..bffdd3468536d 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -2033,7 +2033,7 @@
   Curl_HttpReq httpreq = data->state.httpreq;
   const char *request;
   if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
-     data->set.upload)
+     data->state.upload)
     httpreq = HTTPREQ_PUT;
 
   /* Now set the 'request' pointer to the proper request string */
@@ -2423,7 +2423,7 @@ CURLcode Curl_http_body(struct Curl_easy *data, struct connectdata *conn,
     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 */
diff --git a/lib/imap.c b/lib/imap.c
index c2f675d4b2618..1952e66a1efcd 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -1511,11 +1511,11 @@ static CURLcode imap_done(struct Curl_easy *data, CURLcode status,
     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(data, IMAP_FETCH_FINAL);
     else {
       /* End the APPEND command first by sending an empty line */
@@ -1581,7 +1581,7 @@ static CURLcode imap_perform(struct Curl_easy *data, bool *connected,
     selected = TRUE;
 
   /* Start the first command in the DO phase */
-  if(data->set.upload || data->set.mimepost.kind != MIMEKIND_NONE)
+  if(data->state.upload || data->set.mimepost.kind != MIMEKIND_NONE)
     /* APPEND can be executed directly */
     result = imap_perform_append(data);
   else if(imap->custom && (selected || !imap->mailbox))
diff --git a/lib/rtsp.c b/lib/rtsp.c
index ea99d720ec4eb..ccd7264b00e74 100644
--- a/lib/rtsp.c
+++ b/lib/rtsp.c
@@ -493,7 +493,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
      rtspreq == RTSPREQ_SET_PARAMETER ||
      rtspreq == RTSPREQ_GET_PARAMETER) {
 
-    if(data->set.upload) {
+    if(data->state.upload) {
       putsize = data->state.infilesize;
       data->state.httpreq = HTTPREQ_PUT;
 
@@ -512,7 +512,7 @@ static CURLcode rtsp_do(struct Curl_easy *data, bool *done)
         result =
           Curl_dyn_addf(&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;
       }
diff --git a/lib/setopt.c b/lib/setopt.c
index 38f5711e44191..0c3b9634d1192 100644
--- a/lib/setopt.c
+++ b/lib/setopt.c
@@ -333,8 +333,8 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
      * 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.method = HTTPREQ_PUT;
       data->set.opt_no_body = FALSE; /* this is implied */
@@ -625,7 +625,6 @@
     }
     else
       data->set.method = HTTPREQ_GET;
-    data->set.upload = FALSE;
     break;
 
   case CURLOPT_HTTPPOST:
@@ -888,7 +887,6 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param)
      */
     if(va_arg(param, long)) {
       data->set.method = HTTPREQ_GET;
-      data->set.upload = FALSE; /* switch off upload */
       data->set.opt_no_body = FALSE; /* this is implied */
     }
     break;
diff --git a/lib/smb.c b/lib/smb.c
index a1e444ee6b97e..d6822213529bc 100644
--- a/lib/smb.c
+++ b/lib/smb.c
@@ -530,7 +530,7 @@ static CURLcode smb_send_open(struct Curl_easy *data)
   byte_count = strlen(req->path);
   msg.name_length = smb_swap16((unsigned short)byte_count);
   msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL);
-  if(data->set.upload) {
+  if(data->state.upload) {
     msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE);
     msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF);
   }
@@ -762,7 +762,7 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done)
   void *msg = NULL;
   const struct smb_nt_create_response *smb_m;
 
-  if(data->set.upload && (data->state.infilesize < 0)) {
+  if(data->state.upload && (data->state.infilesize < 0)) {
     failf(data, "SMB upload needs to know the size up front");
     return CURLE_SEND_ERROR;
   }
@@ -813,7 +813,7 @@ static CURLcode smb_request_state(struct Curl_easy *data, bool *done)
     smb_m = (const struct smb_nt_create_response*) msg;
     req->fid = smb_swap16(smb_m->fid);
     data->req.offset = 0;
-    if(data->set.upload) {
+    if(data->state.upload) {
       data->req.size = data->state.infilesize;
       Curl_pgrsSetUploadSize(data, data->req.size);
       next_state = SMB_UPLOAD;
diff --git a/lib/smtp.c b/lib/smtp.c
index 7a030308d4689..c182cace742d7 100644
--- a/lib/smtp.c
+++ b/lib/smtp.c
@@ -1419,7 +1419,7 @@ static CURLcode smtp_done(struct Curl_easy *data, CURLcode status,
     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.
@@ -1511,7 +1511,7 @@ static CURLcode smtp_perform(struct Curl_easy *data, bool *connected,
   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(data);
   else
diff --git a/lib/tftp.c b/lib/tftp.c
index 164d3c723c5b9..8ed1b887b4d21 100644
--- a/lib/tftp.c
+++ b/lib/tftp.c
@@ -370,7 +370,7 @@ static CURLcode tftp_parse_option_ack(struct tftp_state_data *state,
 
       /* 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;
@@ -451,7 +451,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
       return result;
     }
 
-    if(data->set.upload) {
+    if(data->state.upload) {
       /* If we are uploading, send an WRQ */
       setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
       state->data->req.upload_fromhere =
@@ -486,7 +486,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
     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
@@ -540,7 +540,7 @@ static CURLcode tftp_send_first(struct tftp_state_data *state,
     break;
 
   case TFTP_EVENT_OACK:
-    if(data->set.upload) {
+    if(data->state.upload) {
       result = tftp_connect_for_tx(state, event);
     }
     else {
diff --git a/lib/transfer.c b/lib/transfer.c
index e9ab8fbf09510..cb69f3365855a 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1293,6 +1293,7 @@ void Curl_init_CONNECT(struct Curl_easy *data)
 {
   data->state.fread_func = data->set.fread_func_set;
   data->state.in = data->set.in_set;
+  data->state.upload = (data->state.httpreq == HTTPREQ_PUT);
 }
 
 /*
@@ -1767,7 +1767,6 @@
          data->state.httpreq != HTTPREQ_POST_MIME) ||
         !(data->set.keep_post & CURL_REDIR_POST_303))) {
       data->state.httpreq = HTTPREQ_GET;
-      data->set.upload = false;
       infof(data, "Switch to %s",
             data->set.opt_no_body?"HEAD":"GET");
     }
@@ -1770,7 +1770,7 @@ CURLcode Curl_retry_request(struct Curl_easy *data, char **url)
 
   /* 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;
 
diff --git a/lib/urldata.h b/lib/urldata.h
index cca992a0295aa..a8580bdb66fe8 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1487,6 +1487,7 @@
   BIT(url_alloc);   /* URL string is malloc()'ed */
   BIT(referer_alloc); /* referer string is malloc()ed */
   BIT(wildcard_resolve); /* Set to true if any resolve change is a wildcard */
+  BIT(upload);         /* upload request */
 };
 
 /*
@@ -1838,7 +1839,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 */
diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c
index b31f741ba9492..d60edaa303642 100644
--- a/lib/vssh/libssh.c
+++ b/lib/vssh/libssh.c
@@ -1209,7 +1209,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
     }
 
     case SSH_SFTP_TRANS_INIT:
-      if(data->set.upload)
+      if(data->state.upload)
         state(data, SSH_SFTP_UPLOAD_INIT);
       else {
         if(protop->path[strlen(protop->path)-1] == '/')
@@ -1802,7 +1802,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
       /* 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;
@@ -1907,7 +1907,7 @@ static CURLcode myssh_statemach_act(struct Curl_easy *data, bool *block)
         break;
       }
     case SSH_SCP_DONE:
-      if(data->set.upload)
+      if(data->state.upload)
         state(data, SSH_SCP_SEND_EOF);
       else
         state(data, SSH_SCP_CHANNEL_FREE);
diff --git a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c
index f1154dc47a74e..f2e5352d1fd3a 100644
--- a/lib/vssh/libssh2.c
+++ b/lib/vssh/libssh2.c
@@ -2019,7 +2019,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
     }
 
     case SSH_SFTP_TRANS_INIT:
-      if(data->set.upload)
+      if(data->state.upload)
         state(data, SSH_SFTP_UPLOAD_INIT);
       else {
         if(sshp->path[strlen(sshp->path)-1] == '/')
@@ -2691,7 +2691,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
         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;
@@ -2831,7 +2831,7 @@ static CURLcode ssh_statemach_act(struct Curl_easy *data, bool *block)
     break;
 
     case SSH_SCP_DONE:
-      if(data->set.upload)
+      if(data->state.upload)
         state(data, SSH_SCP_SEND_EOF);
       else
         state(data, SSH_SCP_CHANNEL_FREE);
diff --git a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c
index 17d59ecd23bc8..2ca91b7363b1d 100644
--- a/lib/vssh/wolfssh.c
+++ b/lib/vssh/wolfssh.c
@@ -557,7 +557,7 @@ static CURLcode wssh_statemach_act(struct Curl_easy *data, bool *block)
       }
       break;
     case SSH_SFTP_TRANS_INIT:
-      if(data->set.upload)
+      if(data->state.upload)
         state(data, SSH_SFTP_UPLOAD_INIT);
       else {
         if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')