diff --git a/0004-curl-8.6.0-http_chunks-fix-the-accounting-of-consumed-bytes.patch b/0004-curl-8.6.0-http_chunks-fix-the-accounting-of-consumed-bytes.patch new file mode 100644 index 0000000..39b2f31 --- /dev/null +++ b/0004-curl-8.6.0-http_chunks-fix-the-accounting-of-consumed-bytes.patch @@ -0,0 +1,83 @@ +From c7438ccfceee373a75d6d890259cf2e6b5e0e203 Mon Sep 17 00:00:00 2001 +From: Stefan Eissing +Date: Wed, 14 Feb 2024 16:27:23 +0100 +Subject: [PATCH] http_chunks: fix the accounting of consumed bytes + +Prior to this change chunks were handled correctly although in verbose +mode libcurl could incorrectly warn of "Leftovers after chunking" even +if there were none. + +Reported-by: Michael Kaufmann + +Fixes https://github.com/curl/curl/issues/12937 +Closes https://github.com/curl/curl/pull/12939 + +(cherry picked from commit 59e2c78af3a5588d6e6ae6d2223b222f067e054b) +Signed-off-by: Jan Macku +--- + lib/http_chunks.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/lib/http_chunks.c b/lib/http_chunks.c +index 039c179c4..ad1ee9ada 100644 +--- a/lib/http_chunks.c ++++ b/lib/http_chunks.c +@@ -152,6 +152,7 @@ static CURLcode httpchunk_readwrite(struct Curl_easy *data, + ch->hexbuffer[ch->hexindex++] = *buf; + buf++; + blen--; ++ (*pconsumed)++; + } + else { + char *endptr; +@@ -189,6 +190,7 @@ static CURLcode httpchunk_readwrite(struct Curl_easy *data, + + buf++; + blen--; ++ (*pconsumed)++; + break; + + case CHUNK_DATA: +@@ -236,6 +238,7 @@ static CURLcode httpchunk_readwrite(struct Curl_easy *data, + } + buf++; + blen--; ++ (*pconsumed)++; + break; + + case CHUNK_TRAILER: +@@ -293,6 +296,7 @@ static CURLcode httpchunk_readwrite(struct Curl_easy *data, + } + buf++; + blen--; ++ (*pconsumed)++; + break; + + case CHUNK_TRAILER_CR: +@@ -300,6 +304,7 @@ static CURLcode httpchunk_readwrite(struct Curl_easy *data, + ch->state = CHUNK_TRAILER_POSTCR; + buf++; + blen--; ++ (*pconsumed)++; + } + else { + ch->state = CHUNK_FAILED; +@@ -320,6 +325,7 @@ static CURLcode httpchunk_readwrite(struct Curl_easy *data, + /* skip if CR */ + buf++; + blen--; ++ (*pconsumed)++; + } + /* now wait for the final LF */ + ch->state = CHUNK_STOP; +@@ -328,6 +334,7 @@ static CURLcode httpchunk_readwrite(struct Curl_easy *data, + case CHUNK_STOP: + if(*buf == 0x0a) { + blen--; ++ (*pconsumed)++; + /* Record the length of any data left in the end of the buffer + even if there's no more chunks to read */ + ch->datasize = blen; +-- +2.43.2 + diff --git a/0005-curl-8.6.0-CVE-2024-2004.patch b/0005-curl-8.6.0-CVE-2024-2004.patch new file mode 100644 index 0000000..770c391 --- /dev/null +++ b/0005-curl-8.6.0-CVE-2024-2004.patch @@ -0,0 +1,138 @@ +From c8dac4ba172c145dbdf924a5e309fe7539b3610e Mon Sep 17 00:00:00 2001 +From: Daniel Gustafsson +Date: Tue, 27 Feb 2024 15:43:56 +0100 +Subject: [PATCH 1/2] 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 +(cherry picked from commit 17d302e56221f5040092db77d4f85086e8a20e0e) +Signed-off-by: Jan Macku +--- + 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 a5270773f..3891eb679 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; +@@ -2657,22 +2661,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 cd393da75..011aa4607 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 test1475 test1476 test1477 test1478 \ ++test1471 test1472 test1473 test1474 test1475 test1476 test1477 test1478 \ + \ + 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.44.0 + diff --git a/0006-curl-8.6.0-CVE-2024-2398.patch b/0006-curl-8.6.0-CVE-2024-2398.patch new file mode 100644 index 0000000..a431c53 --- /dev/null +++ b/0006-curl-8.6.0-CVE-2024-2398.patch @@ -0,0 +1,95 @@ +From 62ff9aab364ca19cf858972aa1b1f00042763a8a 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 + +(cherry picked from commit deca8039991886a559b67bcd6701db800a5cf764) +Signed-off-by: Jan Macku +--- + lib/http2.c | 34 +++++++++++++++------------------- + 1 file changed, 15 insertions(+), 19 deletions(-) + +diff --git a/lib/http2.c b/lib/http2.c +index c3157d1ef..501dc355f 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) + { +@@ -317,15 +326,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; + } +@@ -872,7 +873,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) { +@@ -917,11 +917,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)); +@@ -1468,14 +1464,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.44.0 + diff --git a/0007-curl-8.6.0-CVE-2024-6197.patch b/0007-curl-8.6.0-CVE-2024-6197.patch new file mode 100644 index 0000000..ae5bf6c --- /dev/null +++ b/0007-curl-8.6.0-CVE-2024-6197.patch @@ -0,0 +1,25 @@ +From 5e1d97ac8d3ffebfaf50afe8641486ffc17ec9ba Mon Sep 17 00:00:00 2001 +From: z2_ <88509734+z2-2z@users.noreply.github.com> +Date: Fri, 28 Jun 2024 14:45:47 +0200 +Subject: [PATCH] x509asn1: remove superfluous free() + +(cherry picked from commit 3a537a4db9e65e545ec45b1b5d5575ee09a2569d) +--- + lib/vtls/x509asn1.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/lib/vtls/x509asn1.c b/lib/vtls/x509asn1.c +index da079361d..2ccf6327a 100644 +--- a/lib/vtls/x509asn1.c ++++ b/lib/vtls/x509asn1.c +@@ -389,7 +389,6 @@ utf8asn1str(struct dynbuf *to, int type, const char *from, const char *end) + if(wc >= 0x00000800) { + if(wc >= 0x00010000) { + if(wc >= 0x00200000) { +- free(buf); + /* Invalid char. size for target encoding. */ + return CURLE_WEIRD_SERVER_REPLY; + } +-- +2.45.2 + diff --git a/0008-curl-8.6.0-speed-throttling-precision-issues.patch b/0008-curl-8.6.0-speed-throttling-precision-issues.patch new file mode 100644 index 0000000..6d52194 --- /dev/null +++ b/0008-curl-8.6.0-speed-throttling-precision-issues.patch @@ -0,0 +1,45 @@ +From 6db0d23dea968e65091261b9daa69325557e5ad0 Mon Sep 17 00:00:00 2001 +From: Stefan Eissing +Date: Tue, 5 Mar 2024 11:08:55 +0100 +Subject: [PATCH 1/2] transfer.c: break receive loop in speed limited transfers + +- the change breaks looping in transfer.c receive for transfers that are + speed limited on having gotten *some* bytes. +- the overall speed limit timing is done in multi.c + +Reported-by: Dmitry Karpov +Bug: https://curl.se/mail/lib-2024-03/0001.html +Closes #13050 + +(cherry picked from commit db5c9f4f9e0779b49624752b135281a0717b277b) +--- + lib/transfer.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/lib/transfer.c b/lib/transfer.c +index 3ae4b61c0..6ceefd637 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -492,13 +492,14 @@ static CURLcode readwrite_data(struct Curl_easy *data, + buf = data->state.buffer; + bytestoread = data->set.buffer_size; + +- /* Observe any imposed speed limit */ + if(bytestoread && data->set.max_recv_speed) { +- curl_off_t net_limit = data->set.max_recv_speed - total_received; +- if(net_limit <= 0) ++ /* In case of speed limit on receiving: if this loop already got ++ * data, break out. If not, limit the amount of bytes to receive. ++ * The overall, timed, speed limiting is done in multi.c */ ++ if(total_received) + break; +- if((size_t)net_limit < bytestoread) +- bytestoread = (size_t)net_limit; ++ if((size_t)data->set.max_recv_speed < bytestoread) ++ bytestoread = (size_t)data->set.max_recv_speed; + } + + nread = Curl_xfer_recv_resp(data, buf, bytestoread, +-- +2.45.2 + diff --git a/0009-curl-8.6.0-speed-limiting-fix-for-32bit-systems.patch b/0009-curl-8.6.0-speed-limiting-fix-for-32bit-systems.patch new file mode 100644 index 0000000..4928dfb --- /dev/null +++ b/0009-curl-8.6.0-speed-limiting-fix-for-32bit-systems.patch @@ -0,0 +1,41 @@ +From 478cab9651d332d1bcb02114895d5a664ce6725a Mon Sep 17 00:00:00 2001 +From: Stefan Eissing +Date: Fri, 26 Jul 2024 10:38:45 +0200 +Subject: [PATCH 2/2] transfer: speed limiting fix for 32bit systems + +When checking if a speed limit on receives applies, compare the receive +sizes using the large int type to prevent an overflow on systems where +size_t is 32bit. + +Fixes #14272 +Reported-by: Mamoru Tasaka +Closes #14277 + +(cherry picked from commit fc273027f16df2dd1eb66ffc7df417f605199e35) +--- + lib/transfer.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/lib/transfer.c b/lib/transfer.c +index 6ceefd637..66e444aa1 100644 +--- a/lib/transfer.c ++++ b/lib/transfer.c +@@ -492,13 +492,13 @@ static CURLcode readwrite_data(struct Curl_easy *data, + buf = data->state.buffer; + bytestoread = data->set.buffer_size; + +- if(bytestoread && data->set.max_recv_speed) { ++ if(bytestoread && data->set.max_recv_speed > 0) { + /* In case of speed limit on receiving: if this loop already got + * data, break out. If not, limit the amount of bytes to receive. + * The overall, timed, speed limiting is done in multi.c */ + if(total_received) + break; +- if((size_t)data->set.max_recv_speed < bytestoread) ++ if(data->set.max_recv_speed < (curl_off_t)bytestoread) + bytestoread = (size_t)data->set.max_recv_speed; + } + +-- +2.45.2 + diff --git a/curl.spec b/curl.spec index 33f4fba..54b8b20 100644 --- a/curl.spec +++ b/curl.spec @@ -1,7 +1,7 @@ Summary: A utility for getting files from remote servers (FTP, HTTP, and others) Name: curl Version: 8.6.0 -Release: 6%{?dist} +Release: 10%{?dist} License: curl Source0: https://curl.se/download/%{name}-%{version}.tar.xz Source1: https://curl.se/download/%{name}-%{version}.tar.xz.asc @@ -21,6 +21,26 @@ Patch002: 0002-curl-8.6.0-ignore-response-body-to-HEAD.patch # it breaks pycurl tests suite Patch003: 0003-curl-8.6.0-vtls-revert-receive-max-buffer-add-test-case.patch +# Fix: Leftovers after chunking should not be part of the curl buffer output +Patch004: 0004-curl-8.6.0-http_chunks-fix-the-accounting-of-consumed-bytes.patch + +# fix Usage of disabled protocol (CVE-2024-2004) +Patch005: 0005-curl-8.6.0-CVE-2024-2004.patch + +# fix HTTP/2 push headers memory-leak (CVE-2024-2398) +Patch006: 0006-curl-8.6.0-CVE-2024-2398.patch + +# fix freeing stack buffer in utf8asn1str (CVE-2024-6197) +Patch007: 0007-curl-8.6.0-CVE-2024-6197.patch + +# fix speed throttling precision issues in transfer.c +# https://curl.se/mail/lib-2024-03/0001.html +Patch008: 0008-curl-8.6.0-speed-throttling-precision-issues.patch + +# fix speed limiting fix for 32bit systems +# https://github.com/curl/curl/issues/14272 +Patch009: 0009-curl-8.6.0-speed-limiting-fix-for-32bit-systems.patch + # patch making libcurl multilib ready Patch101: 0101-curl-7.32.0-multilib.patch @@ -411,6 +431,20 @@ rm -f ${RPM_BUILD_ROOT}%{_mandir}/man1/mk-ca-bundle.1* %{_libdir}/libcurl.so.4.[0-9].[0-9].minimal %changelog +* Tue Jul 30 2024 Jan Macku - 8.6.0-10 +- fix speed throttling precision issues in transfer.c +- fix speed limiting fix for 32bit systems + +* Thu Jul 25 2024 Jan Macku - 8.6.0-9 +- fix freeing stack buffer in utf8asn1str (CVE-2024-6197) + +* Wed Apr 03 2024 Jan Macku - 8.6.0-8 +- fix Usage of disabled protocol (CVE-2024-2004) +- fix HTTP/2 push headers memory-leak (CVE-2024-2398) + +* Mon Feb 19 2024 Jan Macku - 8.6.0-7 +- Fix: Leftovers after chunking should not be part of the curl buffer output (#2264220) + * Mon Feb 12 2024 Jan Macku - 8.6.0-6 - revert "receive max buffer" + add test case - temporarily disable test 0313