From fd4e24d409b597b6763dca8c14d6fb603a29efba Mon Sep 17 00:00:00 2001 From: sherlock2010 <15151851377@163.com> Date: Mon, 1 Apr 2024 07:40:13 +0000 Subject: [PATCH] fix CVE-2024-2004 CVE-2024-2398 (cherry picked from commit dd68bf8b01e10e49326060bc794f42650d05d82d) --- backport-CVE-2024-2004.patch | 139 +++++++++++++++++++++++++++ backport-CVE-2024-2398.patch | 96 +++++++++++++++++++ backport-pre-CVE-2024-2004.patch | 159 +++++++++++++++++++++++++++++++ curl.spec | 11 ++- 4 files changed, 404 insertions(+), 1 deletion(-) create mode 100644 backport-CVE-2024-2004.patch create mode 100644 backport-CVE-2024-2398.patch create mode 100644 backport-pre-CVE-2024-2004.patch diff --git a/backport-CVE-2024-2004.patch b/backport-CVE-2024-2004.patch new file mode 100644 index 0000000..b8d947b --- /dev/null +++ b/backport-CVE-2024-2004.patch @@ -0,0 +1,139 @@ +From 17d302e56221f5040092db77d4f85086e8a20e0e Mon Sep 17 00:00:00 2001 +From: Daniel Gustafsson +Date: Tue, 27 Feb 2024 15:43:56 +0100 +Subject: [PATCH] setopt: Fix disabling all protocols + +When disabling all protocols without enabling any, the resulting +set of allowed protocols remained the default set. Clearing the +allowed set before inspecting the passed value from --proto make +the set empty even in the errorpath of no protocols enabled. + +Co-authored-by: Dan Fandrich +Reported-by: Dan Fandrich +Reviewed-by: Daniel Stenberg +Closes: #13004 + +Conflict:Context adapt +Reference:https://github.com/curl/curl/commit/17d302e56221f5040092db77d4f85086e8a20e0e +--- + lib/setopt.c | 16 ++++++++-------- + tests/data/Makefile.inc | 2 +- + tests/data/test1474 | 42 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 51 insertions(+), 9 deletions(-) + create mode 100644 tests/data/test1474 + +diff --git a/lib/setopt.c b/lib/setopt.c +index 6a4990cce..ce1321fc8 100644 +--- a/lib/setopt.c ++++ b/lib/setopt.c +@@ -155,6 +155,12 @@ static CURLcode setstropt_userpwd(char *option, char **userp, char **passwdp) + + static CURLcode protocol2num(const char *str, curl_prot_t *val) + { ++ /* ++ * We are asked to cherry-pick protocols, so play it safe and disallow all ++ * protocols to start with, and re-add the wanted ones back in. ++ */ ++ *val = 0; ++ + if(!str) + return CURLE_BAD_FUNCTION_ARGUMENT; + +@@ -163,8 +169,6 @@ static CURLcode protocol2num(const char *str, curl_prot_t *val) + return CURLE_OK; + } + +- *val = 0; +- + do { + const char *token = str; + size_t tlen; +@@ -2654,22 +2658,18 @@ CURLcode Curl_vsetopt(struct Curl_easy *data, CURLoption option, va_list param) + break; + + case CURLOPT_PROTOCOLS_STR: { +- curl_prot_t prot; + argptr = va_arg(param, char *); +- result = protocol2num(argptr, &prot); ++ result = protocol2num(argptr, &data->set.allowed_protocols); + if(result) + return result; +- data->set.allowed_protocols = prot; + break; + } + + case CURLOPT_REDIR_PROTOCOLS_STR: { +- curl_prot_t prot; + argptr = va_arg(param, char *); +- result = protocol2num(argptr, &prot); ++ result = protocol2num(argptr, &data->set.redir_protocols); + if(result) + return result; +- data->set.redir_protocols = prot; + break; + } + +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index c20f90d94..b80ffb618 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -187,7 +187,7 @@ test1439 test1440 test1441 test1442 test1443 test1444 test1445 test1446 \ + test1447 test1448 test1449 test1450 test1451 test1452 test1453 test1454 \ + test1455 test1456 test1457 test1458 test1459 test1460 test1461 test1462 \ + test1463 test1464 test1465 test1466 test1467 test1468 test1469 test1470 \ +-test1471 test1472 test1473 \ ++test1471 test1472 test1473 test1474 \ + \ + test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \ + test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \ +diff --git a/tests/data/test1474 b/tests/data/test1474 +new file mode 100644 +index 000000000..c66fa2810 +--- /dev/null ++++ b/tests/data/test1474 +@@ -0,0 +1,42 @@ ++ ++ ++ ++HTTP ++HTTP GET ++--proto ++ ++ ++ ++# ++# Server-side ++ ++ ++ ++ ++ ++# ++# Client-side ++ ++ ++none ++ ++ ++http ++ ++ ++--proto -all disables all protocols ++ ++ ++--proto -all http://%HOSTIP:%NOLISTENPORT/%TESTNUMBER ++ ++ ++ ++# ++# Verify data after the test has been "shot" ++ ++# 1 - Protocol "http" disabled ++ ++1 ++ ++ ++ +-- +2.33.0 + diff --git a/backport-CVE-2024-2398.patch b/backport-CVE-2024-2398.patch new file mode 100644 index 0000000..c3128b1 --- /dev/null +++ b/backport-CVE-2024-2398.patch @@ -0,0 +1,96 @@ +From deca8039991886a559b67bcd6701db800a5cf764 Mon Sep 17 00:00:00 2001 +From: Stefan Eissing +Date: Wed, 6 Mar 2024 09:36:08 +0100 +Subject: [PATCH] http2: push headers better cleanup + +- provide common cleanup method for push headers + +Closes #13054 + +Conflict:struct h2_stream_ctx *stream => struct stream_ctx *stream +Context adapt +Reference:https://github.com/curl/curl/commit/deca8039991886a559b67bcd6701db800a5cf764 +--- + lib/http2.c | 34 +++++++++++++++------------------- + 1 file changed, 15 insertions(+), 19 deletions(-) + +diff --git a/lib/http2.c b/lib/http2.c +index c63ecd383..96868728a 100644 +--- a/lib/http2.c ++++ b/lib/http2.c +@@ -271,6 +271,15 @@ static CURLcode http2_data_setup(struct Curl_cfilter *cf, + return CURLE_OK; + } + ++static void free_push_headers(struct stream_ctx *stream) ++{ ++ size_t i; ++ for(i = 0; ipush_headers_used; i++) ++ free(stream->push_headers[i]); ++ Curl_safefree(stream->push_headers); ++ stream->push_headers_used = 0; ++} ++ + static void http2_data_done(struct Curl_cfilter *cf, + struct Curl_easy *data, bool premature) + { +@@ -306,15 +315,7 @@ static void http2_data_done(struct Curl_cfilter *cf, + Curl_bufq_free(&stream->recvbuf); + Curl_h1_req_parse_free(&stream->h1); + Curl_dynhds_free(&stream->resp_trailers); +- if(stream->push_headers) { +- /* if they weren't used and then freed before */ +- for(; stream->push_headers_used > 0; --stream->push_headers_used) { +- free(stream->push_headers[stream->push_headers_used - 1]); +- } +- free(stream->push_headers); +- stream->push_headers = NULL; +- } +- ++ free_push_headers(stream); + free(stream); + H2_STREAM_LCTX(data) = NULL; + } +@@ -860,7 +861,6 @@ static int push_promise(struct Curl_cfilter *cf, + struct curl_pushheaders heads; + CURLMcode rc; + CURLcode result; +- size_t i; + /* clone the parent */ + struct Curl_easy *newhandle = h2_duphandle(cf, data); + if(!newhandle) { +@@ -905,11 +905,7 @@ static int push_promise(struct Curl_cfilter *cf, + Curl_set_in_callback(data, false); + + /* free the headers again */ +- for(i = 0; ipush_headers_used; i++) +- free(stream->push_headers[i]); +- free(stream->push_headers); +- stream->push_headers = NULL; +- stream->push_headers_used = 0; ++ free_push_headers(stream); + + if(rv) { + DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT)); +@@ -1430,14 +1426,14 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame, + if(stream->push_headers_alloc > 1000) { + /* this is beyond crazy many headers, bail out */ + failf(data_s, "Too many PUSH_PROMISE headers"); +- Curl_safefree(stream->push_headers); ++ free_push_headers(stream); + return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + } + stream->push_headers_alloc *= 2; +- headp = Curl_saferealloc(stream->push_headers, +- stream->push_headers_alloc * sizeof(char *)); ++ headp = realloc(stream->push_headers, ++ stream->push_headers_alloc * sizeof(char *)); + if(!headp) { +- stream->push_headers = NULL; ++ free_push_headers(stream); + return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + } + stream->push_headers = headp; +-- +2.33.0 + diff --git a/backport-pre-CVE-2024-2004.patch b/backport-pre-CVE-2024-2004.patch new file mode 100644 index 0000000..d297555 --- /dev/null +++ b/backport-pre-CVE-2024-2004.patch @@ -0,0 +1,159 @@ +From de0cd5e8e7c9a0cbf28c4a9dec998ad4b6dfa08c Mon Sep 17 00:00:00 2001 +From: Daniel Stenberg +Date: Mon, 11 Dec 2023 23:17:26 +0100 +Subject: [PATCH] test1474: removed + +The test was already somewhat flaky and disabled on several platforms, +and after 1da640abb688 even more unstable. + +Conflict:Context adapt +Reference:https://github.com/curl/curl/commit/de0cd5e8e7c9a0cbf28c4a9dec998ad4b6dfa08c +--- + tests/data/Makefile.inc | 2 +- + tests/data/test1474 | 121 ---------------------------------------- + 2 files changed, 1 insertion(+), 122 deletions(-) + delete mode 100644 tests/data/test1474 + +diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc +index de13c525e..6d1a2ad13 100644 +--- a/tests/data/Makefile.inc ++++ b/tests/data/Makefile.inc +@@ -186,7 +186,7 @@ test1439 test1440 test1441 test1442 test1443 test1444 test1445 test1446 \ + test1447 test1448 test1449 test1450 test1451 test1452 test1453 test1454 \ + test1455 test1456 test1457 test1458 test1459 test1460 test1461 test1462 \ + test1463 test1464 test1465 test1466 test1467 test1468 test1469 test1470 \ +-test1471 test1472 test1473 test1474 \ ++test1471 test1472 test1473 \ + \ + test1500 test1501 test1502 test1503 test1504 test1505 test1506 test1507 \ + test1508 test1509 test1510 test1511 test1512 test1513 test1514 test1515 \ +diff --git a/tests/data/test1474 b/tests/data/test1474 +deleted file mode 100644 +index a87044d1a..000000000 +--- a/tests/data/test1474 ++++ /dev/null +@@ -1,121 +0,0 @@ +- +-# This test is quite timing dependent and tricky to set up. The time line of +-# test operations looks like this: +-# +-# 1. curl sends a PUT request with Expect: 100-continue and waits only 1 msec +-# for a 100 response. +-# 2. The HTTP server accepts the connection but waits 500 msec before acting +-# on the request. +-# 3. curl doesn't receive the expected 100 response before its timeout expires, +-# so it starts sending the body. It is throttled by a --limit-rate, so it +-# sends the first 64 KiB then stops for 1000 msec due to this +-# throttling. +-# 4. The server sends its 417 response while curl is throttled. +-# 5. curl responds to this 417 response by closing the connection (because it +-# has a half-completed response outstanding) and starting a new one. This +-# new request does not have an Expect: header so it is sent without delay. +-# It's still throttled, however, so it takes about 16 seconds to finish +-# sending. +-# 6. The server receives the response and this time acks it with 200. +-# +-# Because of the timing sensitivity (scheduling delays of 500 msec can cause +-# the test to fail), this test is marked flaky to avoid it being run in the CI +-# builds which are often run on overloaded servers. +-# Increasing the --limit-rate would decrease the test time, but at the cost of +-# becoming even more sensitive to delays (going from 500 msec to 250 msec or +-# less of accepted delay before failure). Adding a --speed-time would increase +-# the 1 second delay between writes to longer, but it would also increase the +-# total time needed by the test, which is already quite high. +-# +-# The assumption in step 3 is also broken on NetBSD 9.3, OpenBSD 7.3 and +-# Solaris 10 as they only usually send about half the requested amount of data +-# (see https://curl.se/mail/lib-2023-09/0021.html). +- +- +-HTTP +-HTTP PUT +-Expect +-flaky +-timing-dependent +- +- +-# Server-side +- +-# 417 means the server didn't like the Expect header +- +-HTTP/1.1 417 BAD swsbounce +-Date: Tue, 09 Nov 2010 14:49:00 GMT +-Server: test-server/fake +-Content-Length: 0 +- +- +- +-HTTP/1.1 200 OK +-Date: Tue, 09 Nov 2010 14:49:00 GMT +-Server: test-server/fake +-Content-Length: 10 +- +-blablabla +- +- +-HTTP/1.1 417 BAD swsbounce +-Date: Tue, 09 Nov 2010 14:49:00 GMT +-Server: test-server/fake +-Content-Length: 0 +- +-HTTP/1.1 200 OK +-Date: Tue, 09 Nov 2010 14:49:00 GMT +-Server: test-server/fake +-Content-Length: 10 +- +-blablabla +- +- +-no-expect +-delay: 500 +-connection-monitor +- +- +- +-# Client-side +- +- +-http +- +- +-HTTP PUT with Expect: 100-continue and 417 response during upload +- +- +-http://%HOSTIP:%HTTPPORT/we/want/%TESTNUMBER -T %LOGDIR/test%TESTNUMBER.txt --limit-rate 64K --expect100-timeout 0.001 +- +- +-perl -e "print 'Test does not work on this BSD system' if ( $^O eq 'netbsd' || $^O eq 'openbsd' || ($^O eq 'solaris' && qx/uname -r/ * 100 <= 510));" +- +-# Must be large enough to trigger curl's automatic 100-continue behaviour +- +-%repeat[132 x S]%%repeat[16462 x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%0a]% +- +- +- +-# Verify data after the test has been "shot" +- +- +-PUT /we/want/%TESTNUMBER HTTP/1.1 +-Host: %HOSTIP:%HTTPPORT +-User-Agent: curl/%VERSION +-Accept: */* +-Content-Length: 1053701 +-Expect: 100-continue +- +-%repeat[132 x S]%%repeat[1021 x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%0a]%%repeat[60 x x]%[DISCONNECT] +-PUT /we/want/%TESTNUMBER HTTP/1.1 +-Host: %HOSTIP:%HTTPPORT +-User-Agent: curl/%VERSION +-Accept: */* +-Content-Length: 1053701 +- +-%repeat[132 x S]%%repeat[16462 x xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%0a]% +-[DISCONNECT] +- +- +- +-- +2.33.0 + diff --git a/curl.spec b/curl.spec index 9c3d9e4..d64b733 100644 --- a/curl.spec +++ b/curl.spec @@ -6,7 +6,7 @@ Name: curl Version: 8.4.0 -Release: 1 +Release: 2 Summary: Curl is used in command lines or scripts to transfer data License: curl URL: https://curl.se/ @@ -19,6 +19,9 @@ Patch11: backport-CVE-2023-46218.patch Patch12: backport-0001-CVE-2023-46219.patch Patch13: backport-0002-CVE-2023-46219.patch Patch15: backport-openssl-avoid-BN_num_bits-NULL-pointer-derefs.patch +Patch16: backport-pre-CVE-2024-2004.patch +Patch17: backport-CVE-2024-2004.patch +Patch18: backport-CVE-2024-2398.patch BuildRequires: automake brotli-devel coreutils gcc groff krb5-devel BuildRequires: libidn2-devel libnghttp2-devel libpsl-devel @@ -203,6 +206,12 @@ rm -rf ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la %{_mandir}/man3/* %changelog +* Mon Apr 01 2024 zhouyihang - 8.4.0-2 +- Type:CVE +- CVE:CVE-2024-2004 CVE-2024-2398 +- SUG:NA +- DESC:fix CVE-2024-2004 CVE-2024-2398 + * Tue Jan 09 2024 zhouyihang - 8.4.0-1 - Type:requirement - CVE:NA