Compare commits

...
Sign in to create a new pull request.

5 commits

Author SHA1 Message Date
Jan Macku
4b8b6169a0 fix speed limiting fix for 32bit systems
Resolves: #2301597
2024-07-30 14:48:09 +02:00
Jan Macku
6ce0a7ff37 Resolves: CVE-2024-6197 - freeing stack buffer in utf8asn1str 2024-07-25 15:02:41 +02:00
Jan Macku
b042b47525 Resolves: CVE-2024-2398 - HTTP/2 push headers memory-leak 2024-04-03 16:00:37 +02:00
Jan Macku
2e7c137de7 Resolves: CVE-2024-2004 - Usage of disabled protocol 2024-04-03 16:00:34 +02:00
Jan Macku
f5a882f121 fix: Leftovers after chunking should not be part of the curl buffer output
Resolves: #2264220
2024-02-19 13:25:28 +01:00
7 changed files with 462 additions and 1 deletions

View file

@ -0,0 +1,83 @@
From c7438ccfceee373a75d6d890259cf2e6b5e0e203 Mon Sep 17 00:00:00 2001
From: Stefan Eissing <stefan@eissing.org>
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 <jamacku@redhat.com>
---
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

View file

@ -0,0 +1,138 @@
From c8dac4ba172c145dbdf924a5e309fe7539b3610e Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <daniel@yesql.se>
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 <dan@telarity.com>
Reported-by: Dan Fandrich <dan@telarity.com>
Reviewed-by: Daniel Stenberg <daniel@haxx.se>
Closes: #13004
(cherry picked from commit 17d302e56221f5040092db77d4f85086e8a20e0e)
Signed-off-by: Jan Macku <jamacku@redhat.com>
---
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 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+--proto
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+none
+</server>
+<features>
+http
+</features>
+<name>
+--proto -all disables all protocols
+</name>
+<command>
+--proto -all http://%HOSTIP:%NOLISTENPORT/%TESTNUMBER
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+# 1 - Protocol "http" disabled
+<errorcode>
+1
+</errorcode>
+</verify>
+</testcase>
--
2.44.0

View file

@ -0,0 +1,95 @@
From 62ff9aab364ca19cf858972aa1b1f00042763a8a Mon Sep 17 00:00:00 2001
From: Stefan Eissing <stefan@eissing.org>
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 <jamacku@redhat.com>
---
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; i<stream->push_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; i<stream->push_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

View file

@ -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

View file

@ -0,0 +1,45 @@
From 6db0d23dea968e65091261b9daa69325557e5ad0 Mon Sep 17 00:00:00 2001
From: Stefan Eissing <stefan@eissing.org>
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

View file

@ -0,0 +1,41 @@
From 478cab9651d332d1bcb02114895d5a664ce6725a Mon Sep 17 00:00:00 2001
From: Stefan Eissing <stefan@eissing.org>
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

View file

@ -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 <jamacku@redhat.com> - 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 <jamacku@redhat.com> - 8.6.0-9
- fix freeing stack buffer in utf8asn1str (CVE-2024-6197)
* Wed Apr 03 2024 Jan Macku <jamacku@redhat.com> - 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 <jamacku@redhat.com> - 8.6.0-7
- Fix: Leftovers after chunking should not be part of the curl buffer output (#2264220)
* Mon Feb 12 2024 Jan Macku <jamacku@redhat.com> - 8.6.0-6
- revert "receive max buffer" + add test case
- temporarily disable test 0313