mirror of
https://git.yoctoproject.org/poky
synced 2026-04-13 14:02:21 +02:00
curl: Fix CVE-2020-8284, CVE-2020-8285, CVE-2020-8286
Backport the CVE patches from upstream
https://github.com/curl/curl/commit/ec9cc725d598ac
a95a6ce6b8
https://github.com/curl/curl/commit/69a358f2186e04
https://github.com/curl/curl/commit/d9d01672785b.patch
0002-remove-void-protop-create-union-p.patch is added because the CVE-2020-8285 fix is
dependent on it.
CVE:
CVE-2020-8284
CVE-2020-8285
CVE-2020-8286
(From OE-Core rev: f1a0ea55c0ae2cce7f7c3c6c73f57c5b8222c860)
Signed-off-by: Khairul Rohaizzat Jamaluddin <khairul.rohaizzat.jamaluddin@intel.com>
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
committed by
Richard Purdie
parent
d8a902440c
commit
dbde090045
File diff suppressed because it is too large
Load Diff
210
meta/recipes-support/curl/curl/CVE-2020-8284.patch
Normal file
210
meta/recipes-support/curl/curl/CVE-2020-8284.patch
Normal file
@@ -0,0 +1,210 @@
|
||||
From ec9cc725d598ac77de7b6df8afeec292b3c8ad46 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Stenberg <daniel@haxx.se>
|
||||
Date: Tue, 24 Nov 2020 14:56:57 +0100
|
||||
Subject: [PATCH] ftp: CURLOPT_FTP_SKIP_PASV_IP by default
|
||||
|
||||
The command line tool also independently sets --ftp-skip-pasv-ip by
|
||||
default.
|
||||
|
||||
Ten test cases updated to adapt the modified --libcurl output.
|
||||
|
||||
Bug: https://curl.se/docs/CVE-2020-8284.html
|
||||
CVE-2020-8284
|
||||
|
||||
Reported-by: Varnavas Papaioannou
|
||||
|
||||
Upstream-Status: Backport [https://github.com/curl/curl/commit/ec9cc725d598ac]
|
||||
|
||||
CVE: CVE-2020-8284
|
||||
|
||||
Signed-off-by: Daniel Stenberg <daniel@haxx.se>
|
||||
Signed-off-by: Khairul Rohaizzat Jamaluddin <khairul.rohaizzat.jamaluddin@intel.com>
|
||||
---
|
||||
docs/cmdline-opts/ftp-skip-pasv-ip.d | 2 ++
|
||||
docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 | 8 +++++---
|
||||
lib/url.c | 1 +
|
||||
src/tool_cfgable.c | 1 +
|
||||
tests/data/test1400 | 1 +
|
||||
tests/data/test1401 | 1 +
|
||||
tests/data/test1402 | 1 +
|
||||
tests/data/test1403 | 1 +
|
||||
tests/data/test1404 | 1 +
|
||||
tests/data/test1405 | 1 +
|
||||
tests/data/test1406 | 1 +
|
||||
tests/data/test1407 | 1 +
|
||||
tests/data/test1420 | 1 +
|
||||
14 files changed, 18 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/docs/cmdline-opts/ftp-skip-pasv-ip.d b/docs/cmdline-opts/ftp-skip-pasv-ip.d
|
||||
index d6fd4589b1e..bcf4e7e62f2 100644
|
||||
--- a/docs/cmdline-opts/ftp-skip-pasv-ip.d
|
||||
+++ b/docs/cmdline-opts/ftp-skip-pasv-ip.d
|
||||
@@ -10,4 +10,6 @@ to curl's PASV command when curl connects the data connection. Instead curl
|
||||
will re-use the same IP address it already uses for the control
|
||||
connection.
|
||||
|
||||
+Since curl 7.74.0 this option is enabled by default.
|
||||
+
|
||||
This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
|
||||
diff --git a/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3 b/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3
|
||||
index d6217d0d8ca..fa87ddce769 100644
|
||||
--- a/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3
|
||||
+++ b/docs/libcurl/opts/CURLOPT_FTP_SKIP_PASV_IP.3
|
||||
@@ -5,7 +5,7 @@
|
||||
.\" * | (__| |_| | _ <| |___
|
||||
.\" * \___|\___/|_| \_\_____|
|
||||
.\" *
|
||||
-.\" * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
+.\" * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
.\" *
|
||||
.\" * This software is licensed as described in the file COPYING, which
|
||||
.\" * you should have received as part of this distribution. The terms
|
||||
@@ -35,11 +35,13 @@ address it already uses for the control connection. But it will use the port
|
||||
number from the 227-response.
|
||||
|
||||
This option thus allows libcurl to work around broken server installations
|
||||
-that due to NATs, firewalls or incompetence report the wrong IP address back.
|
||||
+that due to NATs, firewalls or incompetence report the wrong IP address
|
||||
+back. Setting the option also reduces the risk for various sorts of client
|
||||
+abuse by malicious servers.
|
||||
|
||||
This option has no effect if PORT, EPRT or EPSV is used instead of PASV.
|
||||
.SH DEFAULT
|
||||
-0
|
||||
+1 since 7.74.0, was 0 before then.
|
||||
.SH PROTOCOLS
|
||||
FTP
|
||||
.SH EXAMPLE
|
||||
diff --git a/lib/url.c b/lib/url.c
|
||||
index f8b2a0030de..2b0ba87ba87 100644
|
||||
--- a/lib/url.c
|
||||
+++ b/lib/url.c
|
||||
@@ -497,6 +497,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data)
|
||||
set->ftp_use_eprt = TRUE; /* FTP defaults to EPRT operations */
|
||||
set->ftp_use_pret = FALSE; /* mainly useful for drftpd servers */
|
||||
set->ftp_filemethod = FTPFILE_MULTICWD;
|
||||
+ set->ftp_skip_ip = TRUE; /* skip PASV IP by default */
|
||||
#endif
|
||||
set->dns_cache_timeout = 60; /* Timeout every 60 seconds by default */
|
||||
|
||||
diff --git a/src/tool_cfgable.c b/src/tool_cfgable.c
|
||||
index c52d8e1c6bb..4c06d3557b7 100644
|
||||
--- a/src/tool_cfgable.c
|
||||
+++ b/src/tool_cfgable.c
|
||||
@@ -44,6 +44,7 @@ void config_init(struct OperationConfig *config)
|
||||
config->tcp_nodelay = TRUE; /* enabled by default */
|
||||
config->happy_eyeballs_timeout_ms = CURL_HET_DEFAULT;
|
||||
config->http09_allowed = FALSE;
|
||||
+ config->ftp_skip_ip = TRUE;
|
||||
}
|
||||
|
||||
static void free_config_fields(struct OperationConfig *config)
|
||||
diff --git a/tests/data/test1400 b/tests/data/test1400
|
||||
index 812ad0b88d9..b7060eca58e 100644
|
||||
--- a/tests/data/test1400
|
||||
+++ b/tests/data/test1400
|
||||
@@ -73,6 +73,7 @@ int main(int argc, char *argv[])
|
||||
curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped");
|
||||
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
|
||||
|
||||
/* Here is a list of options the curl code used that cannot get generated
|
||||
diff --git a/tests/data/test1401 b/tests/data/test1401
|
||||
index f93b3d637de..a2629683aff 100644
|
||||
--- a/tests/data/test1401
|
||||
+++ b/tests/data/test1401
|
||||
@@ -87,6 +87,7 @@ int main(int argc, char *argv[])
|
||||
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
|
||||
curl_easy_setopt(hnd, CURLOPT_COOKIE, "chocolate=chip");
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_PROTOCOLS, (long)CURLPROTO_FILE |
|
||||
(long)CURLPROTO_FTP |
|
||||
diff --git a/tests/data/test1402 b/tests/data/test1402
|
||||
index 7593c516da1..1bd55cb4e3b 100644
|
||||
--- a/tests/data/test1402
|
||||
+++ b/tests/data/test1402
|
||||
@@ -78,6 +78,7 @@ int main(int argc, char *argv[])
|
||||
curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped");
|
||||
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
|
||||
|
||||
/* Here is a list of options the curl code used that cannot get generated
|
||||
diff --git a/tests/data/test1403 b/tests/data/test1403
|
||||
index ecb4dd3dcab..a7c9fcca322 100644
|
||||
--- a/tests/data/test1403
|
||||
+++ b/tests/data/test1403
|
||||
@@ -73,6 +73,7 @@ int main(int argc, char *argv[])
|
||||
curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped");
|
||||
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
|
||||
|
||||
/* Here is a list of options the curl code used that cannot get generated
|
||||
diff --git a/tests/data/test1404 b/tests/data/test1404
|
||||
index 97622b63948..1d8e8cf7779 100644
|
||||
--- a/tests/data/test1404
|
||||
+++ b/tests/data/test1404
|
||||
@@ -147,6 +147,7 @@ int main(int argc, char *argv[])
|
||||
curl_easy_setopt(hnd, CURLOPT_USERAGENT, "stripped");
|
||||
curl_easy_setopt(hnd, CURLOPT_MAXREDIRS, 50L);
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
|
||||
|
||||
/* Here is a list of options the curl code used that cannot get generated
|
||||
diff --git a/tests/data/test1405 b/tests/data/test1405
|
||||
index 2bac79eda74..b4087704f7b 100644
|
||||
--- a/tests/data/test1405
|
||||
+++ b/tests/data/test1405
|
||||
@@ -89,6 +89,7 @@ int main(int argc, char *argv[])
|
||||
curl_easy_setopt(hnd, CURLOPT_POSTQUOTE, slist2);
|
||||
curl_easy_setopt(hnd, CURLOPT_PREQUOTE, slist3);
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
|
||||
|
||||
/* Here is a list of options the curl code used that cannot get generated
|
||||
diff --git a/tests/data/test1406 b/tests/data/test1406
|
||||
index 51a166adff2..38f68d11ee1 100644
|
||||
--- a/tests/data/test1406
|
||||
+++ b/tests/data/test1406
|
||||
@@ -79,6 +79,7 @@ int main(int argc, char *argv[])
|
||||
curl_easy_setopt(hnd, CURLOPT_URL, "smtp://%HOSTIP:%SMTPPORT/1406");
|
||||
curl_easy_setopt(hnd, CURLOPT_UPLOAD, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_MAIL_FROM, "sender@example.com");
|
||||
curl_easy_setopt(hnd, CURLOPT_MAIL_RCPT, slist1);
|
||||
diff --git a/tests/data/test1407 b/tests/data/test1407
|
||||
index f6879008fb2..a7e13ba7585 100644
|
||||
--- a/tests/data/test1407
|
||||
+++ b/tests/data/test1407
|
||||
@@ -62,6 +62,7 @@ int main(int argc, char *argv[])
|
||||
curl_easy_setopt(hnd, CURLOPT_DIRLISTONLY, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_USERPWD, "user:secret");
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
|
||||
|
||||
/* Here is a list of options the curl code used that cannot get generated
|
||||
diff --git a/tests/data/test1420 b/tests/data/test1420
|
||||
index 057ecc4773a..4b8d7bbf418 100644
|
||||
--- a/tests/data/test1420
|
||||
+++ b/tests/data/test1420
|
||||
@@ -67,6 +67,7 @@ int main(int argc, char *argv[])
|
||||
curl_easy_setopt(hnd, CURLOPT_URL, "imap://%HOSTIP:%IMAPPORT/1420/;MAILINDEX=1");
|
||||
curl_easy_setopt(hnd, CURLOPT_USERPWD, "user:secret");
|
||||
curl_easy_setopt(hnd, CURLOPT_VERBOSE, 1L);
|
||||
+ curl_easy_setopt(hnd, CURLOPT_FTP_SKIP_PASV_IP, 1L);
|
||||
curl_easy_setopt(hnd, CURLOPT_TCP_KEEPALIVE, 1L);
|
||||
|
||||
/* Here is a list of options the curl code used that cannot get generated
|
||||
|
||||
257
meta/recipes-support/curl/curl/CVE-2020-8285.patch
Normal file
257
meta/recipes-support/curl/curl/CVE-2020-8285.patch
Normal file
@@ -0,0 +1,257 @@
|
||||
From 69a358f2186e04cf44698b5100332cbf1ee7f01d Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Stenberg <daniel@haxx.se>
|
||||
Date: Sat, 28 Nov 2020 00:27:21 +0100
|
||||
Subject: [PATCH] ftp: make wc_statemach loop instead of recurse
|
||||
|
||||
CVE-2020-8285
|
||||
|
||||
Fixes #6255
|
||||
Bug: https://curl.se/docs/CVE-2020-8285.html
|
||||
Reported-by: xnynx on github
|
||||
|
||||
Upstream-Status: Backport [https://github.com/curl/curl/commit/69a358f2186e04]
|
||||
|
||||
CVE: CVE-2020-8285
|
||||
|
||||
Signed-off-by: Daniel Stenberg <daniel@haxx.se>
|
||||
Signed-off-by: Khairul Rohaizzat Jamaluddin <khairul.rohaizzat.jamaluddin@intel.com>
|
||||
---
|
||||
lib/ftp.c | 202 +++++++++++++++++++++++++++---------------------------
|
||||
1 file changed, 102 insertions(+), 100 deletions(-)
|
||||
|
||||
diff --git a/lib/ftp.c b/lib/ftp.c
|
||||
index 50e7d7ddac9..bc355742172 100644
|
||||
--- a/lib/ftp.c
|
||||
+++ b/lib/ftp.c
|
||||
@@ -3800,129 +3800,131 @@ static CURLcode init_wc_data(struct connectdata *conn)
|
||||
return result;
|
||||
}
|
||||
|
||||
-/* This is called recursively */
|
||||
static CURLcode wc_statemach(struct connectdata *conn)
|
||||
{
|
||||
struct WildcardData * const wildcard = &(conn->data->wildcard);
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
- switch(wildcard->state) {
|
||||
- case CURLWC_INIT:
|
||||
- result = init_wc_data(conn);
|
||||
- if(wildcard->state == CURLWC_CLEAN)
|
||||
- /* only listing! */
|
||||
- break;
|
||||
- wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
|
||||
- break;
|
||||
+ for(;;) {
|
||||
+ switch(wildcard->state) {
|
||||
+ case CURLWC_INIT:
|
||||
+ result = init_wc_data(conn);
|
||||
+ if(wildcard->state == CURLWC_CLEAN)
|
||||
+ /* only listing! */
|
||||
+ return result;
|
||||
+ wildcard->state = result ? CURLWC_ERROR : CURLWC_MATCHING;
|
||||
+ return result;
|
||||
|
||||
- case CURLWC_MATCHING: {
|
||||
- /* In this state is LIST response successfully parsed, so lets restore
|
||||
- previous WRITEFUNCTION callback and WRITEDATA pointer */
|
||||
- struct ftp_wc *ftpwc = wildcard->protdata;
|
||||
- conn->data->set.fwrite_func = ftpwc->backup.write_function;
|
||||
- conn->data->set.out = ftpwc->backup.file_descriptor;
|
||||
- ftpwc->backup.write_function = ZERO_NULL;
|
||||
- ftpwc->backup.file_descriptor = NULL;
|
||||
- wildcard->state = CURLWC_DOWNLOADING;
|
||||
-
|
||||
- if(Curl_ftp_parselist_geterror(ftpwc->parser)) {
|
||||
- /* error found in LIST parsing */
|
||||
- wildcard->state = CURLWC_CLEAN;
|
||||
- return wc_statemach(conn);
|
||||
- }
|
||||
- if(wildcard->filelist.size == 0) {
|
||||
- /* no corresponding file */
|
||||
- wildcard->state = CURLWC_CLEAN;
|
||||
- return CURLE_REMOTE_FILE_NOT_FOUND;
|
||||
+ case CURLWC_MATCHING: {
|
||||
+ /* In this state is LIST response successfully parsed, so lets restore
|
||||
+ previous WRITEFUNCTION callback and WRITEDATA pointer */
|
||||
+ struct ftp_wc *ftpwc = wildcard->protdata;
|
||||
+ conn->data->set.fwrite_func = ftpwc->backup.write_function;
|
||||
+ conn->data->set.out = ftpwc->backup.file_descriptor;
|
||||
+ ftpwc->backup.write_function = ZERO_NULL;
|
||||
+ ftpwc->backup.file_descriptor = NULL;
|
||||
+ wildcard->state = CURLWC_DOWNLOADING;
|
||||
+
|
||||
+ if(Curl_ftp_parselist_geterror(ftpwc->parser)) {
|
||||
+ /* error found in LIST parsing */
|
||||
+ wildcard->state = CURLWC_CLEAN;
|
||||
+ continue;
|
||||
+ }
|
||||
+ if(wildcard->filelist.size == 0) {
|
||||
+ /* no corresponding file */
|
||||
+ wildcard->state = CURLWC_CLEAN;
|
||||
+ return CURLE_REMOTE_FILE_NOT_FOUND;
|
||||
+ }
|
||||
+ continue;
|
||||
}
|
||||
- return wc_statemach(conn);
|
||||
- }
|
||||
|
||||
- case CURLWC_DOWNLOADING: {
|
||||
- /* filelist has at least one file, lets get first one */
|
||||
- struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
- struct curl_fileinfo *finfo = wildcard->filelist.head->ptr;
|
||||
- struct FTP *ftp = conn->data->req.p.ftp;
|
||||
+ case CURLWC_DOWNLOADING: {
|
||||
+ /* filelist has at least one file, lets get first one */
|
||||
+ struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
+ struct curl_fileinfo *finfo = wildcard->filelist.head->ptr;
|
||||
+ struct FTP *ftp = conn->data->req.p.ftp;
|
||||
|
||||
- char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
|
||||
- if(!tmp_path)
|
||||
- return CURLE_OUT_OF_MEMORY;
|
||||
+ char *tmp_path = aprintf("%s%s", wildcard->path, finfo->filename);
|
||||
+ if(!tmp_path)
|
||||
+ return CURLE_OUT_OF_MEMORY;
|
||||
|
||||
- /* switch default ftp->path and tmp_path */
|
||||
- free(ftp->pathalloc);
|
||||
- ftp->pathalloc = ftp->path = tmp_path;
|
||||
-
|
||||
- infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
|
||||
- if(conn->data->set.chunk_bgn) {
|
||||
- long userresponse;
|
||||
- Curl_set_in_callback(conn->data, true);
|
||||
- userresponse = conn->data->set.chunk_bgn(
|
||||
- finfo, wildcard->customptr, (int)wildcard->filelist.size);
|
||||
- Curl_set_in_callback(conn->data, false);
|
||||
- switch(userresponse) {
|
||||
- case CURL_CHUNK_BGN_FUNC_SKIP:
|
||||
- infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
|
||||
- finfo->filename);
|
||||
- wildcard->state = CURLWC_SKIP;
|
||||
- return wc_statemach(conn);
|
||||
- case CURL_CHUNK_BGN_FUNC_FAIL:
|
||||
- return CURLE_CHUNK_FAILED;
|
||||
+ /* switch default ftp->path and tmp_path */
|
||||
+ free(ftp->pathalloc);
|
||||
+ ftp->pathalloc = ftp->path = tmp_path;
|
||||
+
|
||||
+ infof(conn->data, "Wildcard - START of \"%s\"\n", finfo->filename);
|
||||
+ if(conn->data->set.chunk_bgn) {
|
||||
+ long userresponse;
|
||||
+ Curl_set_in_callback(conn->data, true);
|
||||
+ userresponse = conn->data->set.chunk_bgn(
|
||||
+ finfo, wildcard->customptr, (int)wildcard->filelist.size);
|
||||
+ Curl_set_in_callback(conn->data, false);
|
||||
+ switch(userresponse) {
|
||||
+ case CURL_CHUNK_BGN_FUNC_SKIP:
|
||||
+ infof(conn->data, "Wildcard - \"%s\" skipped by user\n",
|
||||
+ finfo->filename);
|
||||
+ wildcard->state = CURLWC_SKIP;
|
||||
+ continue;
|
||||
+ case CURL_CHUNK_BGN_FUNC_FAIL:
|
||||
+ return CURLE_CHUNK_FAILED;
|
||||
+ }
|
||||
}
|
||||
- }
|
||||
|
||||
- if(finfo->filetype != CURLFILETYPE_FILE) {
|
||||
- wildcard->state = CURLWC_SKIP;
|
||||
- return wc_statemach(conn);
|
||||
- }
|
||||
+ if(finfo->filetype != CURLFILETYPE_FILE) {
|
||||
+ wildcard->state = CURLWC_SKIP;
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
|
||||
- ftpc->known_filesize = finfo->size;
|
||||
+ if(finfo->flags & CURLFINFOFLAG_KNOWN_SIZE)
|
||||
+ ftpc->known_filesize = finfo->size;
|
||||
|
||||
- result = ftp_parse_url_path(conn);
|
||||
- if(result)
|
||||
- return result;
|
||||
+ result = ftp_parse_url_path(conn);
|
||||
+ if(result)
|
||||
+ return result;
|
||||
|
||||
- /* we don't need the Curl_fileinfo of first file anymore */
|
||||
- Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
|
||||
+ /* we don't need the Curl_fileinfo of first file anymore */
|
||||
+ Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
|
||||
|
||||
- if(wildcard->filelist.size == 0) { /* remains only one file to down. */
|
||||
- wildcard->state = CURLWC_CLEAN;
|
||||
- /* after that will be ftp_do called once again and no transfer
|
||||
- will be done because of CURLWC_CLEAN state */
|
||||
- return CURLE_OK;
|
||||
+ if(wildcard->filelist.size == 0) { /* remains only one file to down. */
|
||||
+ wildcard->state = CURLWC_CLEAN;
|
||||
+ /* after that will be ftp_do called once again and no transfer
|
||||
+ will be done because of CURLWC_CLEAN state */
|
||||
+ return CURLE_OK;
|
||||
+ }
|
||||
+ return result;
|
||||
}
|
||||
- } break;
|
||||
|
||||
- case CURLWC_SKIP: {
|
||||
- if(conn->data->set.chunk_end) {
|
||||
- Curl_set_in_callback(conn->data, true);
|
||||
- conn->data->set.chunk_end(conn->data->wildcard.customptr);
|
||||
- Curl_set_in_callback(conn->data, false);
|
||||
+ case CURLWC_SKIP: {
|
||||
+ if(conn->data->set.chunk_end) {
|
||||
+ Curl_set_in_callback(conn->data, true);
|
||||
+ conn->data->set.chunk_end(conn->data->wildcard.customptr);
|
||||
+ Curl_set_in_callback(conn->data, false);
|
||||
+ }
|
||||
+ Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
|
||||
+ wildcard->state = (wildcard->filelist.size == 0) ?
|
||||
+ CURLWC_CLEAN : CURLWC_DOWNLOADING;
|
||||
+ continue;
|
||||
}
|
||||
- Curl_llist_remove(&wildcard->filelist, wildcard->filelist.head, NULL);
|
||||
- wildcard->state = (wildcard->filelist.size == 0) ?
|
||||
- CURLWC_CLEAN : CURLWC_DOWNLOADING;
|
||||
- return wc_statemach(conn);
|
||||
- }
|
||||
|
||||
- case CURLWC_CLEAN: {
|
||||
- struct ftp_wc *ftpwc = wildcard->protdata;
|
||||
- result = CURLE_OK;
|
||||
- if(ftpwc)
|
||||
- result = Curl_ftp_parselist_geterror(ftpwc->parser);
|
||||
+ case CURLWC_CLEAN: {
|
||||
+ struct ftp_wc *ftpwc = wildcard->protdata;
|
||||
+ result = CURLE_OK;
|
||||
+ if(ftpwc)
|
||||
+ result = Curl_ftp_parselist_geterror(ftpwc->parser);
|
||||
|
||||
- wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE;
|
||||
- } break;
|
||||
+ wildcard->state = result ? CURLWC_ERROR : CURLWC_DONE;
|
||||
+ return result;
|
||||
+ }
|
||||
|
||||
- case CURLWC_DONE:
|
||||
- case CURLWC_ERROR:
|
||||
- case CURLWC_CLEAR:
|
||||
- if(wildcard->dtor)
|
||||
- wildcard->dtor(wildcard->protdata);
|
||||
- break;
|
||||
+ case CURLWC_DONE:
|
||||
+ case CURLWC_ERROR:
|
||||
+ case CURLWC_CLEAR:
|
||||
+ if(wildcard->dtor)
|
||||
+ wildcard->dtor(wildcard->protdata);
|
||||
+ return result;
|
||||
+ }
|
||||
}
|
||||
-
|
||||
- return result;
|
||||
+ /* UNREACHABLE */
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
131
meta/recipes-support/curl/curl/CVE-2020-8286.patch
Normal file
131
meta/recipes-support/curl/curl/CVE-2020-8286.patch
Normal file
@@ -0,0 +1,131 @@
|
||||
From 5d3b28deac44c19e4d73fc80e4917d42ee43adfe Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Stenberg <daniel@haxx.se>
|
||||
Date: Wed, 2 Dec 2020 23:01:11 +0100
|
||||
Subject: [PATCH] openssl: make the OCSP verification verify the certificate id
|
||||
|
||||
CVE-2020-8286
|
||||
|
||||
Reported by anonymous
|
||||
|
||||
Bug: https://curl.se/docs/CVE-2020-8286.html
|
||||
|
||||
Upstream-Status: Backport [https://github.com/curl/curl/commit/d9d01672785b]
|
||||
|
||||
CVE: CVE-2020-8286
|
||||
|
||||
Signed-off-by: Daniel Stenberg <daniel@haxx.se>
|
||||
Signed-off-by: Khairul Rohaizzat Jamaluddin <khairul.rohaizzat.jamaluddin@intel.com>
|
||||
|
||||
---
|
||||
lib/vtls/openssl.c | 83 +++++++++++++++++++++++++++++++++++-------------------
|
||||
1 file changed, 54 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
|
||||
index 1685a4a..22cbfe7 100644
|
||||
--- a/lib/vtls/openssl.c
|
||||
+++ b/lib/vtls/openssl.c
|
||||
@@ -1777,6 +1777,11 @@ static CURLcode verifystatus(struct connectdata *conn,
|
||||
X509_STORE *st = NULL;
|
||||
STACK_OF(X509) *ch = NULL;
|
||||
struct ssl_backend_data *backend = connssl->backend;
|
||||
+ X509 *cert;
|
||||
+ OCSP_CERTID *id = NULL;
|
||||
+ int cert_status, crl_reason;
|
||||
+ ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
|
||||
+ int ret;
|
||||
|
||||
long len = SSL_get_tlsext_status_ocsp_resp(backend->handle, &status);
|
||||
|
||||
@@ -1845,43 +1850,63 @@ static CURLcode verifystatus(struct connectdata *conn,
|
||||
goto end;
|
||||
}
|
||||
|
||||
- for(i = 0; i < OCSP_resp_count(br); i++) {
|
||||
- int cert_status, crl_reason;
|
||||
- OCSP_SINGLERESP *single = NULL;
|
||||
-
|
||||
- ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
|
||||
+ /* Compute the certificate's ID */
|
||||
+ cert = SSL_get_peer_certificate(backend->handle);
|
||||
+ if(!cert) {
|
||||
+ failf(data, "Error getting peer certficate");
|
||||
+ result = CURLE_SSL_INVALIDCERTSTATUS;
|
||||
+ goto end;
|
||||
+ }
|
||||
|
||||
- single = OCSP_resp_get0(br, i);
|
||||
- if(!single)
|
||||
- continue;
|
||||
+ for(i = 0; i < sk_X509_num(ch); i++) {
|
||||
+ X509 *issuer = sk_X509_value(ch, i);
|
||||
+ if(X509_check_issued(issuer, cert) == X509_V_OK) {
|
||||
+ id = OCSP_cert_to_id(EVP_sha1(), cert, issuer);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ X509_free(cert);
|
||||
|
||||
- cert_status = OCSP_single_get0_status(single, &crl_reason, &rev,
|
||||
- &thisupd, &nextupd);
|
||||
+ if(!id) {
|
||||
+ failf(data, "Error computing OCSP ID");
|
||||
+ result = CURLE_SSL_INVALIDCERTSTATUS;
|
||||
+ goto end;
|
||||
+ }
|
||||
|
||||
- if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) {
|
||||
- failf(data, "OCSP response has expired");
|
||||
- result = CURLE_SSL_INVALIDCERTSTATUS;
|
||||
- goto end;
|
||||
- }
|
||||
+ /* Find the single OCSP response corresponding to the certificate ID */
|
||||
+ ret = OCSP_resp_find_status(br, id, &cert_status, &crl_reason, &rev,
|
||||
+ &thisupd, &nextupd);
|
||||
+ OCSP_CERTID_free(id);
|
||||
+ if(ret != 1) {
|
||||
+ failf(data, "Could not find certificate ID in OCSP response");
|
||||
+ result = CURLE_SSL_INVALIDCERTSTATUS;
|
||||
+ goto end;
|
||||
+ }
|
||||
|
||||
- infof(data, "SSL certificate status: %s (%d)\n",
|
||||
- OCSP_cert_status_str(cert_status), cert_status);
|
||||
+ /* Validate the corresponding single OCSP response */
|
||||
+ if(!OCSP_check_validity(thisupd, nextupd, 300L, -1L)) {
|
||||
+ failf(data, "OCSP response has expired");
|
||||
+ result = CURLE_SSL_INVALIDCERTSTATUS;
|
||||
+ goto end;
|
||||
+ }
|
||||
|
||||
- switch(cert_status) {
|
||||
- case V_OCSP_CERTSTATUS_GOOD:
|
||||
- break;
|
||||
+ infof(data, "SSL certificate status: %s (%d)\n",
|
||||
+ OCSP_cert_status_str(cert_status), cert_status);
|
||||
|
||||
- case V_OCSP_CERTSTATUS_REVOKED:
|
||||
- result = CURLE_SSL_INVALIDCERTSTATUS;
|
||||
+ switch(cert_status) {
|
||||
+ case V_OCSP_CERTSTATUS_GOOD:
|
||||
+ break;
|
||||
|
||||
- failf(data, "SSL certificate revocation reason: %s (%d)",
|
||||
- OCSP_crl_reason_str(crl_reason), crl_reason);
|
||||
- goto end;
|
||||
+ case V_OCSP_CERTSTATUS_REVOKED:
|
||||
+ result = CURLE_SSL_INVALIDCERTSTATUS;
|
||||
+ failf(data, "SSL certificate revocation reason: %s (%d)",
|
||||
+ OCSP_crl_reason_str(crl_reason), crl_reason);
|
||||
+ goto end;
|
||||
|
||||
- case V_OCSP_CERTSTATUS_UNKNOWN:
|
||||
- result = CURLE_SSL_INVALIDCERTSTATUS;
|
||||
- goto end;
|
||||
- }
|
||||
+ case V_OCSP_CERTSTATUS_UNKNOWN:
|
||||
+ default:
|
||||
+ result = CURLE_SSL_INVALIDCERTSTATUS;
|
||||
+ goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
@@ -7,6 +7,10 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=2e9fb35867314fe31c6a4977ef7dd531"
|
||||
|
||||
SRC_URI = "https://curl.haxx.se/download/curl-${PV}.tar.bz2 \
|
||||
file://0001-replace-krb5-config-with-pkg-config.patch \
|
||||
file://0002-remove-void-protop-create-union-p.patch \
|
||||
file://CVE-2020-8284.patch \
|
||||
file://CVE-2020-8285.patch \
|
||||
file://CVE-2020-8286.patch \
|
||||
"
|
||||
|
||||
SRC_URI[sha256sum] = "ad91970864102a59765e20ce16216efc9d6ad381471f7accceceab7d905703ef"
|
||||
|
||||
Reference in New Issue
Block a user