From a6744913657cc3aa049bbd93b33f7bb26a719476 Mon Sep 17 00:00:00 2001 From: yangl777 Date: Wed, 29 Sep 2021 16:00:12 +0800 Subject: [PATCH] fix CVE-2021-22945 CVE-2021-22946 CVE-2021-22947 --- backport-CVE-2021-22945.patch | 25 +++ backport-CVE-2021-22946.patch | 310 ++++++++++++++++++++++++++++++++ backport-CVE-2021-22947.patch | 328 ++++++++++++++++++++++++++++++++++ curl.spec | 11 +- 4 files changed, 673 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2021-22945.patch create mode 100644 backport-CVE-2021-22946.patch create mode 100644 backport-CVE-2021-22947.patch diff --git a/backport-CVE-2021-22945.patch b/backport-CVE-2021-22945.patch new file mode 100644 index 0000000..258c09a --- /dev/null +++ b/backport-CVE-2021-22945.patch @@ -0,0 +1,25 @@ +From 19483938de0dd2356c6f9a0092b8917aa238df77 Mon Sep 17 00:00:00 2001 +From: z2_ on hackerone <> +Date: Tue, 24 Aug 2021 09:50:33 +0200 +Subject: [PATCH] mqtt: clear the leftovers pointer when sending succeeds + +CVE-2021-22945 + +Bug: https://curl.se/docs/CVE-2021-22945.html +--- + lib/mqtt.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/lib/mqtt.c ++++ b/lib/mqtt.c +@@ -124,6 +124,10 @@ static CURLcode mqtt_send(struct connect + mq->sendleftovers = sendleftovers; + mq->nsend = nsend; + } ++ else { ++ mq->sendleftovers = NULL; ++ mq->nsend = 0; ++ } + return result; + } + diff --git a/backport-CVE-2021-22946.patch b/backport-CVE-2021-22946.patch new file mode 100644 index 0000000..e076cf2 --- /dev/null +++ b/backport-CVE-2021-22946.patch @@ -0,0 +1,310 @@ +Backport of: + +From 96d71feb27e533a8b337512841a537952916262c Mon Sep 17 00:00:00 2001 +From: Patrick Monnerat +Date: Wed, 8 Sep 2021 11:56:22 +0200 +Subject: [PATCH] ftp,imap,pop3: do not ignore --ssl-reqd + +In imap and pop3, check if TLS is required even when capabilities +request has failed. + +In ftp, ignore preauthentication (230 status of server greeting) if TLS +is required. + +Bug: https://curl.se/docs/CVE-2021-22946.html + +CVE-2021-22946 +--- + lib/ftp.c | 9 ++++--- + lib/imap.c | 24 ++++++++---------- + lib/pop3.c | 33 +++++++++++------------- + tests/data/Makefile.inc | 2 ++ + tests/data/test984 | 56 +++++++++++++++++++++++++++++++++++++++++ + tests/data/test985 | 54 +++++++++++++++++++++++++++++++++++++++ + tests/data/test986 | 53 ++++++++++++++++++++++++++++++++++++++ + 7 files changed, 195 insertions(+), 36 deletions(-) + create mode 100644 tests/data/test984 + create mode 100644 tests/data/test985 + create mode 100644 tests/data/test986 + +--- a/lib/ftp.c ++++ b/lib/ftp.c +@@ -2642,9 +2642,12 @@ static CURLcode ftp_statemach_act(struct + /* we have now received a full FTP server response */ + switch(ftpc->state) { + case FTP_WAIT220: +- if(ftpcode == 230) +- /* 230 User logged in - already! */ +- return ftp_state_user_resp(conn, ftpcode, ftpc->state); ++ if(ftpcode == 230) { ++ /* 230 User logged in - already! Take as 220 if TLS required. */ ++ if(data->set.use_ssl <= CURLUSESSL_TRY || ++ conn->bits.ftp_use_control_ssl) ++ return ftp_state_user_resp(conn, ftpcode, ftpc->state); ++ } + else if(ftpcode != 220) { + failf(data, "Got a %03d ftp-server response when 220 was expected", + ftpcode); +--- a/lib/imap.c ++++ b/lib/imap.c +@@ -919,22 +919,18 @@ static CURLcode imap_state_capability_re + line += wordlen; + } + } +- else if(imapcode == IMAP_RESP_OK) { +- if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { +- /* We don't have a SSL/TLS connection yet, but SSL is requested */ +- if(imapc->tls_supported) +- /* Switch to TLS connection now */ +- result = imap_perform_starttls(conn); +- else if(data->set.use_ssl == CURLUSESSL_TRY) +- /* Fallback and carry on with authentication */ +- result = imap_perform_authentication(conn); +- else { +- failf(data, "STARTTLS not supported."); +- result = CURLE_USE_SSL_FAILED; +- } ++ else if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { ++ /* PREAUTH is not compatible with STARTTLS. */ ++ if(imapcode == IMAP_RESP_OK && imapc->tls_supported && !imapc->preauth) { ++ /* Switch to TLS connection now */ ++ result = imap_perform_starttls(conn); + } +- else ++ else if(data->set.use_ssl <= CURLUSESSL_TRY) + result = imap_perform_authentication(conn); ++ else { ++ failf(data, "STARTTLS not available."); ++ result = CURLE_USE_SSL_FAILED; ++ } + } + else + result = imap_perform_authentication(conn); +--- a/lib/pop3.c ++++ b/lib/pop3.c +@@ -723,28 +723,23 @@ static CURLcode pop3_state_capa_resp(str + } + } + } +- else if(pop3code == '+') { +- if(data->set.use_ssl && !conn->ssl[FIRSTSOCKET].use) { +- /* We don't have a SSL/TLS connection yet, but SSL is requested */ +- if(pop3c->tls_supported) +- /* Switch to TLS connection now */ +- result = pop3_perform_starttls(conn); +- else if(data->set.use_ssl == CURLUSESSL_TRY) +- /* Fallback and carry on with authentication */ +- result = pop3_perform_authentication(conn); +- else { +- failf(data, "STLS not supported."); +- result = CURLE_USE_SSL_FAILED; +- } +- } +- else +- result = pop3_perform_authentication(conn); +- } + else { + /* Clear text is supported when CAPA isn't recognised */ +- pop3c->authtypes |= POP3_TYPE_CLEARTEXT; ++ if(pop3code != '+') ++ pop3c->authtypes |= POP3_TYPE_CLEARTEXT; + +- result = pop3_perform_authentication(conn); ++ if(!data->set.use_ssl || conn->ssl[FIRSTSOCKET].use) ++ result = pop3_perform_authentication(conn); ++ else if(pop3code == '+' && pop3c->tls_supported) ++ /* Switch to TLS connection now */ ++ result = pop3_perform_starttls(conn); ++ else if(data->set.use_ssl <= CURLUSESSL_TRY) ++ /* Fallback and carry on with authentication */ ++ result = pop3_perform_authentication(conn); ++ else { ++ failf(data, "STLS not supported."); ++ result = CURLE_USE_SSL_FAILED; ++ } + } + + return result; +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -115,6 +115,8 @@ test945 test946 test947 test948 test949 + test954 test955 test956 test957 test958 test959 test960 test961 test962 \ + test963 test964 test965 test966 test967 test968 test969 test970 test971 \ + \ ++test984 test985 test986 \ ++\ + test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \ + test1008 test1009 test1010 test1011 test1012 test1013 test1014 test1015 \ + test1016 test1017 test1018 test1019 test1020 test1021 test1022 test1023 \ +--- /dev/null ++++ b/tests/data/test984 +@@ -0,0 +1,56 @@ ++ ++ ++ ++IMAP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++REPLY CAPABILITY A001 BAD Not implemented ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++imap ++ ++ ++IMAP require STARTTLS with failing capabilities ++ ++ ++imap://%HOSTIP:%IMAPPORT/%TESTNUMBER -T log/upload%TESTNUMBER -u user:secret --ssl-reqd ++ ++ ++Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST) ++From: Fred Foobar ++Subject: afternoon meeting ++To: joe@example.com ++Message-Id: ++MIME-Version: 1.0 ++Content-Type: TEXT/PLAIN; CHARSET=US-ASCII ++ ++Hello Joe, do you think we can meet at 3:30 tomorrow? ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 64 is CURLE_USE_SSL_FAILED ++ ++64 ++ ++ ++A001 CAPABILITY ++ ++ ++ +--- /dev/null ++++ b/tests/data/test985 +@@ -0,0 +1,54 @@ ++ ++ ++ ++POP3 ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++REPLY CAPA -ERR Not implemented ++ ++ ++From: me@somewhere ++To: fake@nowhere ++ ++body ++ ++-- ++ yours sincerely ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++pop3 ++ ++ ++POP3 require STARTTLS with failing capabilities ++ ++ ++pop3://%HOSTIP:%POP3PORT/%TESTNUMBER -u user:secret --ssl-reqd ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 64 is CURLE_USE_SSL_FAILED ++ ++64 ++ ++ ++CAPA ++ ++ ++ +--- /dev/null ++++ b/tests/data/test986 +@@ -0,0 +1,53 @@ ++ ++ ++ ++FTP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++REPLY welcome 230 Welcome ++REPLY AUTH 500 unknown command ++ ++ ++ ++# Client-side ++ ++ ++SSL ++ ++ ++ftp ++ ++ ++FTP require STARTTLS while preauthenticated ++ ++ ++data ++ to ++ see ++that FTPS ++works ++ so does it? ++ ++ ++--ssl-reqd --ftp-ssl-control ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T log/test%TESTNUMBER.txt -u user:secret ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++# 64 is CURLE_USE_SSL_FAILED ++ ++64 ++ ++ ++AUTH SSL ++AUTH TLS ++ ++ ++ diff --git a/backport-CVE-2021-22947.patch b/backport-CVE-2021-22947.patch new file mode 100644 index 0000000..f0b3c0f --- /dev/null +++ b/backport-CVE-2021-22947.patch @@ -0,0 +1,328 @@ +Backport of: + +From 259b4f2e1fd01fbc55e569ee0a507afeae34f77c Mon Sep 17 00:00:00 2001 +From: Patrick Monnerat +Date: Tue, 7 Sep 2021 13:26:42 +0200 +Subject: [PATCH] ftp,imap,pop3,smtp: reject STARTTLS server response + pipelining + +If a server pipelines future responses within the STARTTLS response, the +former are preserved in the pingpong cache across TLS negotiation and +used as responses to the encrypted commands. + +This fix detects pipelined STARTTLS responses and rejects them with an +error. + +CVE-2021-22947 + +Bug: https://curl.se/docs/CVE-2021-22947.html +--- + lib/ftp.c | 3 +++ + lib/imap.c | 4 +++ + lib/pop3.c | 4 +++ + lib/smtp.c | 4 +++ + tests/data/Makefile.inc | 2 ++ + tests/data/test980 | 52 ++++++++++++++++++++++++++++++++++++ + tests/data/test981 | 59 +++++++++++++++++++++++++++++++++++++++++ + tests/data/test982 | 57 +++++++++++++++++++++++++++++++++++++++ + tests/data/test983 | 52 ++++++++++++++++++++++++++++++++++++ + 9 files changed, 237 insertions(+) + create mode 100644 tests/data/test980 + create mode 100644 tests/data/test981 + create mode 100644 tests/data/test982 + create mode 100644 tests/data/test983 + +--- a/lib/ftp.c ++++ b/lib/ftp.c +@@ -2703,6 +2703,9 @@ static CURLcode ftp_statemach_act(struct + case FTP_AUTH: + /* we have gotten the response to a previous AUTH command */ + ++ if(pp->cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; /* Forbid pipelining in response. */ ++ + /* RFC2228 (page 5) says: + * + * If the server is willing to accept the named security mechanism, +--- a/lib/imap.c ++++ b/lib/imap.c +@@ -948,6 +948,10 @@ static CURLcode imap_state_starttls_resp + + (void)instate; /* no use for this yet */ + ++ /* Pipelining in response is forbidden. */ ++ if(data->conn->proto.imapc.pp.cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; ++ + if(imapcode != IMAP_RESP_OK) { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied"); +--- a/lib/pop3.c ++++ b/lib/pop3.c +@@ -755,6 +755,10 @@ static CURLcode pop3_state_starttls_resp + + (void)instate; /* no use for this yet */ + ++ /* Pipelining in response is forbidden. */ ++ if(data->conn->proto.pop3c.pp.cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; ++ + if(pop3code != '+') { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied"); +--- a/lib/smtp.c ++++ b/lib/smtp.c +@@ -819,6 +819,10 @@ static CURLcode smtp_state_starttls_resp + + (void)instate; /* no use for this yet */ + ++ /* Pipelining in response is forbidden. */ ++ if(data->conn->proto.smtpc.pp.cache_size) ++ return CURLE_WEIRD_SERVER_REPLY; ++ + if(smtpcode != 220) { + if(data->set.use_ssl != CURLUSESSL_TRY) { + failf(data, "STARTTLS denied, code %d", smtpcode); +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -115,6 +115,8 @@ test945 test946 test947 test948 test949 + test954 test955 test956 test957 test958 test959 test960 test961 test962 \ + test963 test964 test965 test966 test967 test968 test969 test970 test971 \ + \ ++test980 test981 test982 test983 \ ++\ + test984 test985 test986 \ + \ + test1000 test1001 test1002 test1003 test1004 test1005 test1006 test1007 \ +--- /dev/null ++++ b/tests/data/test980 +@@ -0,0 +1,52 @@ ++ ++ ++ ++SMTP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++CAPA STARTTLS ++AUTH PLAIN ++REPLY STARTTLS 454 currently unavailable\r\n235 Authenticated\r\n250 2.1.0 Sender ok\r\n250 2.1.5 Recipient ok\r\n354 Enter mail\r\n250 2.0.0 Accepted ++REPLY AUTH 535 5.7.8 Authentication credentials invalid ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++smtp ++ ++ ++SMTP STARTTLS pipelined server response ++ ++ ++mail body ++ ++ ++smtp://%HOSTIP:%SMTPPORT/%TESTNUMBER --mail-rcpt recipient@example.com --mail-from sender@example.com -u user:secret --ssl --sasl-ir -T - ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 8 is CURLE_WEIRD_SERVER_REPLY ++ ++8 ++ ++ ++EHLO %TESTNUMBER ++STARTTLS ++ ++ ++ +--- /dev/null ++++ b/tests/data/test981 +@@ -0,0 +1,59 @@ ++ ++ ++ ++IMAP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++CAPA STARTTLS ++REPLY STARTTLS A002 BAD currently unavailable\r\nA003 OK Authenticated\r\nA004 OK Accepted ++REPLY LOGIN A003 BAD Authentication credentials invalid ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++imap ++ ++ ++IMAP STARTTLS pipelined server response ++ ++ ++imap://%HOSTIP:%IMAPPORT/%TESTNUMBER -T log/upload%TESTNUMBER -u user:secret --ssl ++ ++ ++Date: Mon, 7 Feb 1994 21:52:25 -0800 (PST) ++From: Fred Foobar ++Subject: afternoon meeting ++To: joe@example.com ++Message-Id: ++MIME-Version: 1.0 ++Content-Type: TEXT/PLAIN; CHARSET=US-ASCII ++ ++Hello Joe, do you think we can meet at 3:30 tomorrow? ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 8 is CURLE_WEIRD_SERVER_REPLY ++ ++8 ++ ++ ++A001 CAPABILITY ++A002 STARTTLS ++ ++ ++ +--- /dev/null ++++ b/tests/data/test982 +@@ -0,0 +1,57 @@ ++ ++ ++ ++POP3 ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++CAPA STLS USER ++REPLY STLS -ERR currently unavailable\r\n+OK user accepted\r\n+OK authenticated ++REPLY PASS -ERR Authentication credentials invalid ++ ++ ++From: me@somewhere ++To: fake@nowhere ++ ++body ++ ++-- ++ yours sincerely ++ ++ ++ ++# ++# Client-side ++ ++ ++SSL ++ ++ ++pop3 ++ ++ ++POP3 STARTTLS pipelined server response ++ ++ ++pop3://%HOSTIP:%POP3PORT/%TESTNUMBER -u user:secret --ssl ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 8 is CURLE_WEIRD_SERVER_REPLY ++ ++8 ++ ++ ++CAPA ++STLS ++ ++ ++ +--- /dev/null ++++ b/tests/data/test983 +@@ -0,0 +1,52 @@ ++ ++ ++ ++FTP ++STARTTLS ++ ++ ++ ++# ++# Server-side ++ ++ ++REPLY AUTH 500 unknown command\r\n500 unknown command\r\n331 give password\r\n230 Authenticated\r\n257 "/"\r\n200 OK\r\n200 OK\r\n200 OK\r\n226 Transfer complete ++REPLY PASS 530 Login incorrect ++ ++ ++ ++# Client-side ++ ++ ++SSL ++ ++ ++ftp ++ ++ ++FTP STARTTLS pipelined server response ++ ++ ++data ++ to ++ see ++that FTPS ++works ++ so does it? ++ ++ ++--ssl --ftp-ssl-control ftp://%HOSTIP:%FTPPORT/%TESTNUMBER -T log/test%TESTNUMBER.txt -u user:secret -P %CLIENTIP ++ ++ ++ ++# Verify data after the test has been "shot" ++ ++# 8 is CURLE_WEIRD_SERVER_REPLY ++ ++8 ++ ++ ++AUTH SSL ++ ++ ++ diff --git a/curl.spec b/curl.spec index 2643d0a..9e5c5d3 100644 --- a/curl.spec +++ b/curl.spec @@ -6,7 +6,7 @@ Name: curl Version: 7.71.1 -Release: 10 +Release: 11 Summary: Curl is used in command lines or scripts to transfer data License: MIT URL: https://curl.haxx.se/ @@ -29,6 +29,9 @@ Patch115: backport-CVE-2021-22898.patch Patch116: backport-CVE-2021-22924.patch Patch117: backport-CVE-2021-22925.patch Patch118: backport-CVE-2021-22926.patch +Patch119: backport-CVE-2021-22945.patch +Patch120: backport-CVE-2021-22946.patch +Patch121: backport-CVE-2021-22947.patch BuildRequires: automake brotli-devel coreutils gcc groff krb5-devel BuildRequires: libidn2-devel libmetalink-devel libnghttp2-devel libpsl-devel @@ -170,6 +173,12 @@ rm -rf ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la %{_mandir}/man3/* %changelog +* Wed Sep 29 2021 yanglu - 7.71.1-11 +- Type:CVE +- CVE:CVE-2021-22945 CVE-2021-22946 CVE-2021-22947 +- SUG:NA +- DESC:fix CVE-2021-22945 CVE-2021-22946 CVE-2021-22947 + * Wed Aug 11 2021 gaihuiying - 7.71.1-10 - Type:CVE - CVE:CVE-2021-22925 CVE-2021-22926 -- Gitee