Compare commits

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

14 commits

Author SHA1 Message Date
Kamil Dudka
a591d5e191 Resolves: CVE-2018-14618 - fix NTLM password overflow via integer overflow 2018-09-05 15:03:10 +02:00
Kamil Dudka
85cdb48477 Resolves: #1219544 - ssl: set engine implicitly when a PKCS#11 URI is provided 2018-08-09 16:17:36 +02:00
Kamil Dudka
46b2e3e0ba Resolves: #1585797 - http2: handle GOAWAY properly 2018-06-05 15:34:57 +02:00
Kamil Dudka
5d567e070c Resolves: CVE-2018-1000300 - fix FTP shutdown response buffer overflow 2018-05-18 16:31:16 +02:00
Kamil Dudka
96bc4e6df9 Resolves: CVE-2018-1000301 - http: restore buffer ptr when bad response-line is parsed 2018-05-18 16:27:40 +02:00
Kamil Dudka
50dc31c720 Resolves: CVE-2018-1000120 - fix FTP path trickery leads to NIL byte out of bounds write 2018-03-14 14:23:55 +01:00
Kamil Dudka
b90bebc9a0 Resolves: CVE-2018-1000121 - fix LDAP NULL pointer dereference 2018-03-14 14:22:08 +01:00
Kamil Dudka
5e4110baf6 Resolves: CVE-2018-1000122 - fix RTSP RTP buffer over-read 2018-03-14 14:21:29 +01:00
Kamil Dudka
7328500cf2 Resolves: CVE-2018-1000005 - http2: fix incorrect trailer buffer size 2018-01-24 12:46:09 +01:00
Kamil Dudka
33e53eab66 Resolves: CVE-2018-1000007 - http: prevent custom Authorization headers in redirects 2018-01-24 12:46:08 +01:00
Kamil Dudka
39e642fa56 Resolves: CVE-2017-8816 - fix NTLM buffer overflow via integer overflow 2017-11-30 14:55:47 +01:00
Kamil Dudka
51ef99fe38 Resolves: CVE-2017-8817 - fix FTP wildcard out of bounds read 2017-11-30 14:53:54 +01:00
Kamil Dudka
8535ade159 Resolves: CVE-2017-1000257 - fix buffer overflow while processing IMAP FETCH response 2017-10-23 12:28:58 +02:00
Kamil Dudka
9765ef0484 Resolves: CVE-2017-1000254 - fix out of bounds read in FTP PWD response parser 2017-10-04 10:24:13 +02:00
15 changed files with 2017 additions and 4 deletions

View file

@ -0,0 +1,344 @@
From 01f15fd3d66655872e10c36dd6a631f491fbbed0 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sat, 10 Mar 2018 23:48:43 +0100
Subject: [PATCH 1/2] http2: mark the connection for close on GOAWAY
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
... don't consider it an error!
Assisted-by: Jay Satiro
Reported-by: Łukasz Domeradzki
Fixes #2365
Closes #2375
Upstream-commit: 8b498a875c975294545581282289991bbcfeabf4
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http.h | 5 ++---
lib/http2.c | 33 +++++++++++++++++++++------------
lib/multi.c | 9 +++------
3 files changed, 26 insertions(+), 21 deletions(-)
diff --git a/lib/http.h b/lib/http.h
index a845f56..e8e41e3 100644
--- a/lib/http.h
+++ b/lib/http.h
@@ -7,7 +7,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, 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
@@ -174,8 +174,6 @@ struct HTTP {
size_t pauselen; /* the number of bytes left in data */
bool closed; /* TRUE on HTTP2 stream close */
bool close_handled; /* TRUE if stream closure is handled by libcurl */
- uint32_t error_code; /* HTTP/2 error code */
-
char *mem; /* points to a buffer in memory to store received data */
size_t len; /* size of the buffer 'mem' points to */
size_t memlen; /* size of data copied to mem */
@@ -228,6 +226,7 @@ struct http_conn {
/* list of settings that will be sent */
nghttp2_settings_entry local_settings[3];
size_t local_settings_num;
+ uint32_t error_code; /* HTTP/2 error code */
#else
int unused; /* prevent a compiler warning */
#endif
diff --git a/lib/http2.c b/lib/http2.c
index 0e55801..14ab0f7 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -205,7 +205,6 @@ void Curl_http2_setup_req(struct Curl_easy *data)
http->status_code = -1;
http->pausedata = NULL;
http->pauselen = 0;
- http->error_code = NGHTTP2_NO_ERROR;
http->closed = FALSE;
http->close_handled = FALSE;
http->mem = data->state.buffer;
@@ -218,6 +217,7 @@ void Curl_http2_setup_conn(struct connectdata *conn)
{
conn->proto.httpc.settings.max_concurrent_streams =
DEFAULT_MAX_CONCURRENT_STREAMS;
+ conn->proto.httpc.error_code = NGHTTP2_NO_ERROR;
}
/*
@@ -778,6 +778,7 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
(void)stream_id;
if(stream_id) {
+ struct http_conn *httpc;
/* get the stream from the hash based on Stream ID, stream ID zero is for
connection-oriented stuff */
data_s = nghttp2_session_get_stream_user_data(session, stream_id);
@@ -792,10 +793,11 @@ static int on_stream_close(nghttp2_session *session, int32_t stream_id,
if(!stream)
return NGHTTP2_ERR_CALLBACK_FAILURE;
- stream->error_code = error_code;
stream->closed = TRUE;
data_s->state.drain++;
- conn->proto.httpc.drain_total++;
+ httpc = &conn->proto.httpc;
+ httpc->drain_total++;
+ httpc->error_code = error_code;
/* remove the entry from the hash as the stream is now gone */
nghttp2_session_set_stream_user_data(session, stream_id, 0);
@@ -1223,13 +1225,14 @@ static int h2_session_send(struct Curl_easy *data,
* This function returns 0 if it succeeds, or -1 and error code will
* be assigned to *err.
*/
-static int h2_process_pending_input(struct Curl_easy *data,
+static int h2_process_pending_input(struct connectdata *conn,
struct http_conn *httpc,
CURLcode *err)
{
ssize_t nread;
char *inbuf;
ssize_t rv;
+ struct Curl_easy *data = conn->data;
nread = httpc->inbuflen - httpc->nread_inbuf;
inbuf = httpc->inbuf + httpc->nread_inbuf;
@@ -1267,7 +1270,13 @@ static int h2_process_pending_input(struct Curl_easy *data,
if(should_close_session(httpc)) {
DEBUGF(infof(data,
"h2_process_pending_input: nothing to do in this session\n"));
- *err = CURLE_HTTP2;
+ if(httpc->error_code)
+ *err = CURLE_HTTP2;
+ else {
+ /* not an error per se, but should still close the connection */
+ connclose(conn, "GOAWAY received");
+ *err = CURLE_OK;
+ }
return -1;
}
@@ -1298,7 +1307,7 @@ CURLcode Curl_http2_done_sending(struct connectdata *conn)
that it can signal EOF to nghttp2 */
(void)nghttp2_session_resume_data(h2, stream->stream_id);
- (void)h2_process_pending_input(conn->data, httpc, &result);
+ (void)h2_process_pending_input(conn, httpc, &result);
}
}
return result;
@@ -1322,7 +1331,7 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
data->state.drain = 0;
if(httpc->pause_stream_id == 0) {
- if(h2_process_pending_input(data, httpc, err) != 0) {
+ if(h2_process_pending_input(conn, httpc, err) != 0) {
return -1;
}
}
@@ -1331,10 +1340,10 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
/* Reset to FALSE to prevent infinite loop in readwrite_data function. */
stream->closed = FALSE;
- if(stream->error_code != NGHTTP2_NO_ERROR) {
+ if(httpc->error_code != NGHTTP2_NO_ERROR) {
failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %d)",
- stream->stream_id, Curl_http2_strerror(stream->error_code),
- stream->error_code);
+ stream->stream_id, Curl_http2_strerror(httpc->error_code),
+ httpc->error_code);
*err = CURLE_HTTP2_STREAM;
return -1;
}
@@ -1482,7 +1491,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
/* We have paused nghttp2, but we have no pause data (see
on_data_chunk_recv). */
httpc->pause_stream_id = 0;
- if(h2_process_pending_input(data, httpc, &result) != 0) {
+ if(h2_process_pending_input(conn, httpc, &result) != 0) {
*err = result;
return -1;
}
@@ -1512,7 +1521,7 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
frames, then we have to call it again with 0-length data.
Without this, on_stream_close callback will not be called,
and stream could be hanged. */
- if(h2_process_pending_input(data, httpc, &result) != 0) {
+ if(h2_process_pending_input(conn, httpc, &result) != 0) {
*err = result;
return -1;
}
diff --git a/lib/multi.c b/lib/multi.c
index d5bc532..7b9ba61 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -5,7 +5,7 @@
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2018, 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
@@ -572,11 +572,8 @@ static CURLcode multi_done(struct connectdata **connp,
result = CURLE_ABORTED_BY_CALLBACK;
}
- if(conn->send_pipe.size + conn->recv_pipe.size != 0 &&
- !data->set.reuse_forbid &&
- !conn->bits.close) {
- /* Stop if pipeline is not empty and we do not have to close
- connection. */
+ if(conn->send_pipe.size || conn->recv_pipe.size) {
+ /* Stop if pipeline is not empty . */
data->easy_conn = NULL;
DEBUGF(infof(data, "Connection still in use, no more multi_done now!\n"));
return CURLE_OK;
--
2.14.4
From 84ddda3994c1f12d79946780dee9111b3cf1c308 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 19 Apr 2018 20:03:30 +0200
Subject: [PATCH 2/2] http2: handle GOAWAY properly
When receiving REFUSED_STREAM, mark the connection for close and retry
streams accordingly on another/fresh connection.
Reported-by: Terry Wu
Fixes #2416
Fixes #1618
Closes #2510
Upstream-commit: d122df5972fc01e39ae28e6bca705237d7e3318a
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http2.c | 17 ++++++++++++-----
lib/multi.c | 4 +++-
lib/transfer.c | 17 +++++++++++++++--
lib/urldata.h | 2 +-
4 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/lib/http2.c b/lib/http2.c
index b2c34e9..fba4d70 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -1070,7 +1070,6 @@ void Curl_http2_done(struct connectdata *conn, bool premature)
struct http_conn *httpc = &conn->proto.httpc;
if(http->header_recvbuf) {
- DEBUGF(infof(data, "free header_recvbuf!!\n"));
Curl_add_buffer_free(http->header_recvbuf);
http->header_recvbuf = NULL; /* clear the pointer */
Curl_add_buffer_free(http->trailer_recvbuf);
@@ -1340,7 +1339,15 @@ static ssize_t http2_handle_stream_close(struct connectdata *conn,
/* Reset to FALSE to prevent infinite loop in readwrite_data function. */
stream->closed = FALSE;
- if(httpc->error_code != NGHTTP2_NO_ERROR) {
+ if(httpc->error_code == NGHTTP2_REFUSED_STREAM) {
+ DEBUGF(infof(data, "REFUSED_STREAM (%d), try again on a new connection!\n",
+ stream->stream_id));
+ connclose(conn, "REFUSED_STREAM"); /* don't use this anymore */
+ data->state.refused_stream = TRUE;
+ *err = CURLE_RECV_ERROR; /* trigger Curl_retry_request() later */
+ return -1;
+ }
+ else if(httpc->error_code != NGHTTP2_NO_ERROR) {
failf(data, "HTTP/2 stream %u was not closed cleanly: %s (err %d)",
stream->stream_id, Curl_http2_strerror(httpc->error_code),
httpc->error_code);
@@ -1568,9 +1575,9 @@ static ssize_t http2_recv(struct connectdata *conn, int sockindex,
}
if(nread == 0) {
- failf(data, "Unexpected EOF");
- *err = CURLE_RECV_ERROR;
- return -1;
+ DEBUGF(infof(data, "end of stream\n"));
+ *err = CURLE_OK;
+ return 0;
}
DEBUGF(infof(data, "nread=%zd\n", nread));
diff --git a/lib/multi.c b/lib/multi.c
index 98e5fca..d69e5f9 100644
--- a/lib/multi.c
+++ b/lib/multi.c
@@ -575,7 +575,9 @@ static CURLcode multi_done(struct connectdata **connp,
if(conn->send_pipe.size || conn->recv_pipe.size) {
/* Stop if pipeline is not empty . */
data->easy_conn = NULL;
- DEBUGF(infof(data, "Connection still in use, no more multi_done now!\n"));
+ DEBUGF(infof(data, "Connection still in use %d/%d, "
+ "no more multi_done now!\n",
+ conn->send_pipe.size, conn->recv_pipe.size));
return CURLE_OK;
}
diff --git a/lib/transfer.c b/lib/transfer.c
index fd9af31..5c29cc9 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -1896,7 +1896,7 @@ CURLcode Curl_retry_request(struct connectdata *conn,
char **url)
{
struct Curl_easy *data = conn->data;
-
+ bool retry = FALSE;
*url = NULL;
/* if we're talking upload, we can't do the checks below, unless the protocol
@@ -1909,7 +1909,7 @@ CURLcode Curl_retry_request(struct connectdata *conn,
conn->bits.reuse &&
(!data->set.opt_no_body
|| (conn->handler->protocol & PROTO_FAMILY_HTTP)) &&
- (data->set.rtspreq != RTSPREQ_RECEIVE)) {
+ (data->set.rtspreq != RTSPREQ_RECEIVE))
/* We got no data, we attempted to re-use a connection. For HTTP this
can be a retry so we try again regardless if we expected a body.
For other protocols we only try again only if we expected a body.
@@ -1917,6 +1917,19 @@ CURLcode Curl_retry_request(struct connectdata *conn,
This might happen if the connection was left alive when we were
done using it before, but that was closed when we wanted to read from
it again. Bad luck. Retry the same request on a fresh connect! */
+ retry = TRUE;
+ else if(data->state.refused_stream &&
+ (data->req.bytecount + data->req.headerbytecount == 0) ) {
+ /* This was sent on a refused stream, safe to rerun. A refused stream
+ error can typically only happen on HTTP/2 level if the stream is safe
+ to issue again, but the nghttp2 API can deliver the message to other
+ streams as well, which is why this adds the check the data counters
+ too. */
+ infof(conn->data, "REFUSED_STREAM, retrying a fresh connect\n");
+ data->state.refused_stream = FALSE; /* clear again */
+ retry = TRUE;
+ }
+ if(retry) {
infof(conn->data, "Connection died, retrying a fresh connect\n");
*url = strdup(conn->data->change.url);
if(!*url)
diff --git a/lib/urldata.h b/lib/urldata.h
index 3d7b9e5..6a36ee9 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1391,7 +1391,7 @@ struct UrlState {
curl_off_t current_speed; /* the ProgressShow() function sets this,
bytes / second */
bool this_is_a_follow; /* this is a followed Location: request */
-
+ bool refused_stream; /* this was refused, try again */
char *first_host; /* host name of the first (not followed) request.
if set, this should be the host name that we will
sent authorization to, no else. Used to make Location:
--
2.14.4

View file

@ -0,0 +1,136 @@
From 1e6f9bb225047cb40232ac3e0aa5da161e49d465 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 25 Sep 2017 00:35:22 +0200
Subject: [PATCH] FTP: zero terminate the entry path even on bad input
... a single double quote could leave the entry path buffer without a zero
terminating byte. CVE-2017-1000254
Test 1152 added to verify.
Reported-by: Max Dymond
Bug: https://curl.haxx.se/docs/adv_20171004.html
Upstream-commit: 5ff2c5ff25750aba1a8f64fbcad8e5b891512584
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ftp.c | 7 ++++--
tests/data/Makefile.inc | 1 +
tests/data/test1152 | 61 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 67 insertions(+), 2 deletions(-)
create mode 100644 tests/data/test1152
diff --git a/lib/ftp.c b/lib/ftp.c
index 6e86e53..bcba6bb 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -2777,6 +2777,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
const size_t buf_size = data->set.buffer_size;
char *dir;
char *store;
+ bool entry_extracted = FALSE;
dir = malloc(nread + 1);
if(!dir)
@@ -2808,7 +2809,7 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
}
else {
/* end of path */
- *store = '\0'; /* zero terminate */
+ entry_extracted = TRUE;
break; /* get out of this loop */
}
}
@@ -2817,7 +2818,9 @@ static CURLcode ftp_statemach_act(struct connectdata *conn)
store++;
ptr++;
}
-
+ *store = '\0'; /* zero terminate */
+ }
+ if(entry_extracted) {
/* If the path name does not look like an absolute path (i.e.: it
does not start with a '/'), we probably need some server-dependent
adjustments. For example, this is the case when connecting to
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 1657ac6..f8f6e41 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -121,6 +121,7 @@ test1120 test1121 test1122 test1123 test1124 test1125 test1126 test1127 \
test1128 test1129 test1130 test1131 test1132 test1133 test1134 test1135 \
test1136 test1137 test1138 test1139 test1140 test1141 test1142 test1143 \
test1144 test1145 test1146 test1147 test1148 \
+test1152 \
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
test1216 test1217 test1218 test1219 \
diff --git a/tests/data/test1152 b/tests/data/test1152
new file mode 100644
index 0000000..aa8c0a7
--- /dev/null
+++ b/tests/data/test1152
@@ -0,0 +1,61 @@
+<testcase>
+<info>
+<keywords>
+FTP
+PASV
+LIST
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<servercmd>
+REPLY PWD 257 "just one
+</servercmd>
+
+# When doing LIST, we get the default list output hard-coded in the test
+# FTP server
+<data mode="text">
+total 20
+drwxr-xr-x 8 98 98 512 Oct 22 13:06 .
+drwxr-xr-x 8 98 98 512 Oct 22 13:06 ..
+drwxr-xr-x 2 98 98 512 May 2 1996 curl-releases
+-r--r--r-- 1 0 1 35 Jul 16 1996 README
+lrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin
+dr-xr-xr-x 2 0 1 512 Oct 1 1997 dev
+drwxrwxrwx 2 98 98 512 May 29 16:04 download.html
+dr-xr-xr-x 2 0 1 512 Nov 30 1995 etc
+drwxrwxrwx 2 98 1 512 Oct 30 14:33 pub
+dr-xr-xr-x 5 0 1 512 Oct 1 1997 usr
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+ftp
+</server>
+ <name>
+FTP with uneven quote in PWD response
+ </name>
+ <command>
+ftp://%HOSTIP:%FTPPORT/test-1152/
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER anonymous
+PASS ftp@example.com
+PWD
+CWD test-1152
+EPSV
+TYPE A
+LIST
+QUIT
+</protocol>
+</verify>
+</testcase>
--
2.13.6

View file

@ -0,0 +1,36 @@
From f8b7620e0578ef44e8fd958d32f348b535d1ab77 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sat, 7 Oct 2017 00:11:31 +0200
Subject: [PATCH] imap: if a FETCH response has no size, don't call write
callback
CVE-2017-1000257
Reported-by: Brian Carpenter and 0xd34db347
Also detected by OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3586
Upstream-commit: 13c9a9ded3ae744a1e11cbc14e9146d9fa427040
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/imap.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lib/imap.c b/lib/imap.c
index 48af290..4deba88 100644
--- a/lib/imap.c
+++ b/lib/imap.c
@@ -1091,6 +1091,11 @@ static CURLcode imap_state_fetch_resp(struct connectdata *conn, int imapcode,
/* The conversion from curl_off_t to size_t is always fine here */
chunk = (size_t)size;
+ if(!chunk) {
+ /* no size, we're done with the data */
+ state(conn, IMAP_STOP);
+ return CURLE_OK;
+ }
result = Curl_client_write(conn, CLIENTWRITE_BODY, pp->cache, chunk);
if(result)
return result;
--
2.13.6

View file

@ -0,0 +1,132 @@
From d288bcc0635f154fa2167bb0ac1de554bde971b6 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 10 Nov 2017 08:52:45 +0100
Subject: [PATCH] wildcardmatch: fix heap buffer overflow in setcharset
The code would previous read beyond the end of the pattern string if the
match pattern ends with an open bracket when the default pattern
matching function is used.
Detected by OSS-Fuzz:
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4161
CVE-2017-8817
Bug: https://curl.haxx.se/docs/adv_2017-ae72.html
Upstream-commit: 0b664ba968437715819bfe4c7ada5679d16ebbc3
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/curl_fnmatch.c | 9 +++------
tests/data/Makefile.inc | 1 +
tests/data/test1163 | 52 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 56 insertions(+), 6 deletions(-)
create mode 100644 tests/data/test1163
diff --git a/lib/curl_fnmatch.c b/lib/curl_fnmatch.c
index 46d3ada..5dd5323 100644
--- a/lib/curl_fnmatch.c
+++ b/lib/curl_fnmatch.c
@@ -133,6 +133,9 @@ static int setcharset(unsigned char **p, unsigned char *charset)
unsigned char c;
for(;;) {
c = **p;
+ if(!c)
+ return SETCHARSET_FAIL;
+
switch(state) {
case CURLFNM_SCHS_DEFAULT:
if(ISALNUM(c)) { /* ASCII value */
@@ -196,9 +199,6 @@ static int setcharset(unsigned char **p, unsigned char *charset)
else
return SETCHARSET_FAIL;
}
- else if(c == '\0') {
- return SETCHARSET_FAIL;
- }
else {
charset[c] = 1;
(*p)++;
@@ -277,9 +277,6 @@ static int setcharset(unsigned char **p, unsigned char *charset)
else if(c == ']') {
return SETCHARSET_OK;
}
- else if(c == '\0') {
- return SETCHARSET_FAIL;
- }
else if(ISPRINT(c)) {
charset[c] = 1;
(*p)++;
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index f8f6e41..6e2f402 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -122,6 +122,7 @@ test1128 test1129 test1130 test1131 test1132 test1133 test1134 test1135 \
test1136 test1137 test1138 test1139 test1140 test1141 test1142 test1143 \
test1144 test1145 test1146 test1147 test1148 \
test1152 \
+test1163 \
test1200 test1201 test1202 test1203 test1204 test1205 test1206 test1207 \
test1208 test1209 test1210 test1211 test1212 test1213 test1214 test1215 \
test1216 test1217 test1218 test1219 \
diff --git a/tests/data/test1163 b/tests/data/test1163
new file mode 100644
index 0000000..a109b51
--- /dev/null
+++ b/tests/data/test1163
@@ -0,0 +1,52 @@
+<testcase>
+<info>
+<keywords>
+FTP
+RETR
+LIST
+wildcardmatch
+ftplistparser
+flaky
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+<data>
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+ftp
+</server>
+<tool>
+lib576
+</tool>
+<name>
+FTP wildcard with pattern ending with an open-bracket
+</name>
+<command>
+"ftp://%HOSTIP:%FTPPORT/fully_simulated/DOS/*[]["
+</command>
+</client>
+<verify>
+<protocol>
+USER anonymous
+PASS ftp@example.com
+PWD
+CWD fully_simulated
+CWD DOS
+EPSV
+TYPE A
+LIST
+QUIT
+</protocol>
+# 78 == CURLE_REMOTE_FILE_NOT_FOUND
+<errorcode>
+78
+</errorcode>
+</verify>
+</testcase>
--
2.13.6

View file

@ -0,0 +1,61 @@
From 300d6e1b2598dc34004e4608e6718f1c0c206110 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 6 Nov 2017 23:51:52 +0100
Subject: [PATCH] ntlm: avoid integer overflow for malloc size
Reported-by: Alex Nichols
Assisted-by: Kamil Dudka and Max Dymond
CVE-2017-8816
Bug: https://curl.haxx.se/docs/adv_2017-11e7.html
Upstream-commit: 7f2a1df6f5fc598750b2c6f34465c8d924db28cc
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/curl_ntlm_core.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index aea5452..eb44f97 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -622,6 +622,12 @@ CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
return CURLE_OK;
}
+#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4)
+#define SIZE_T_MAX 18446744073709551615U
+#else
+#define SIZE_T_MAX 4294967295U
+#endif
+
/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
* (uppercase UserName + Domain) as the data
*/
@@ -631,10 +637,20 @@ CURLcode Curl_ntlm_core_mk_ntlmv2_hash(const char *user, size_t userlen,
unsigned char *ntlmv2hash)
{
/* Unicode representation */
- size_t identity_len = (userlen + domlen) * 2;
- unsigned char *identity = malloc(identity_len);
+ size_t identity_len;
+ unsigned char *identity;
CURLcode result = CURLE_OK;
+ /* we do the length checks below separately to avoid integer overflow risk
+ on extreme data lengths */
+ if((userlen > SIZE_T_MAX/2) ||
+ (domlen > SIZE_T_MAX/2) ||
+ ((userlen + domlen) > SIZE_T_MAX/2))
+ return CURLE_OUT_OF_MEMORY;
+
+ identity_len = (userlen + domlen) * 2;
+ identity = malloc(identity_len);
+
if(!identity)
return CURLE_OUT_OF_MEMORY;
--
2.13.6

View file

@ -0,0 +1,330 @@
From e6968d1d220891230bcca5340bfd364183ceaa31 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 19 Jan 2018 13:19:25 +0100
Subject: [PATCH] http: prevent custom Authorization headers in redirects
... unless CURLOPT_UNRESTRICTED_AUTH is set to allow them. This matches how
curl already handles Authorization headers created internally.
Note: this changes behavior slightly, for the sake of reducing mistakes.
Added test 317 and 318 to verify.
Reported-by: Craig de Stigter
Bug: https://curl.haxx.se/docs/adv_2018-b3bf.html
Upstream-commit: af32cd3859336ab963591ca0df9b1e33a7ee066b
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/libcurl/opts/CURLOPT_HTTPHEADER.3 | 12 ++++-
lib/http.c | 10 +++-
lib/url.c | 2 +-
lib/urldata.h | 2 +-
tests/data/Makefile.inc | 2 +-
tests/data/test317 | 94 +++++++++++++++++++++++++++++++++
tests/data/test318 | 95 ++++++++++++++++++++++++++++++++++
7 files changed, 212 insertions(+), 5 deletions(-)
create mode 100644 tests/data/test317
create mode 100644 tests/data/test318
diff --git a/docs/libcurl/opts/CURLOPT_HTTPHEADER.3 b/docs/libcurl/opts/CURLOPT_HTTPHEADER.3
index 6aeec22..781e570 100644
--- a/docs/libcurl/opts/CURLOPT_HTTPHEADER.3
+++ b/docs/libcurl/opts/CURLOPT_HTTPHEADER.3
@@ -5,7 +5,7 @@
.\" * | (__| |_| | _ <| |___
.\" * \___|\___/|_| \_\_____|
.\" *
-.\" * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
+.\" * Copyright (C) 1998 - 2018, 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
@@ -78,6 +78,16 @@ the headers. They may be private or otherwise sensitive to leak.
Use \fICURLOPT_HEADEROPT(3)\fP to make the headers only get sent to where you
intend them to get sent.
+
+Custom headers are sent in all requests done by the easy handles, which
+implies that if you tell libcurl to follow redirects
+(\fICURLOPT_FOLLOWLOCATION(3)\fP), the same set of custom headers will be sent
+in the subsequent request. Redirects can of course go to other hosts and thus
+those servers will get all the contents of your custom headers too.
+
+Starting in 7.58.0, libcurl will specifically prevent "Authorization:" headers
+from being sent to other hosts than the first used one, unless specifically
+permitted with the \fICURLOPT_UNRESTRICTED_AUTH(3)\fP option.
.SH DEFAULT
NULL
.SH PROTOCOLS
diff --git a/lib/http.c b/lib/http.c
index b73e58c..c15208d 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -732,7 +732,7 @@ Curl_http_output_auth(struct connectdata *conn,
if(!data->state.this_is_a_follow ||
conn->bits.netrc ||
!data->state.first_host ||
- data->set.http_disable_hostname_check_before_authentication ||
+ data->set.allow_auth_to_other_hosts ||
strcasecompare(data->state.first_host, conn->host.name)) {
result = output_auth_headers(conn, authhost, request, path, FALSE);
}
@@ -1651,6 +1651,14 @@ CURLcode Curl_add_custom_headers(struct connectdata *conn,
checkprefix("Transfer-Encoding:", headers->data))
/* HTTP/2 doesn't support chunked requests */
;
+ else if(checkprefix("Authorization:", headers->data) &&
+ /* be careful of sending this potentially sensitive header to
+ other hosts */
+ (data->state.this_is_a_follow &&
+ data->state.first_host &&
+ !data->set.allow_auth_to_other_hosts &&
+ !strcasecompare(data->state.first_host, conn->host.name)))
+ ;
else {
CURLcode result = Curl_add_bufferf(req_buffer, "%s\r\n",
headers->data);
diff --git a/lib/url.c b/lib/url.c
index 71d4d8b..ba53131 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -1008,7 +1008,7 @@ CURLcode Curl_setopt(struct Curl_easy *data, CURLoption option,
* Send authentication (user+password) when following locations, even when
* hostname changed.
*/
- data->set.http_disable_hostname_check_before_authentication =
+ data->set.allow_auth_to_other_hosts =
(0 != va_arg(param, long)) ? TRUE : FALSE;
break;
diff --git a/lib/urldata.h b/lib/urldata.h
index b4f18e7..1dd62ae 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -1757,7 +1757,7 @@ struct UserDefined {
bool http_keep_sending_on_error; /* for HTTP status codes >= 300 */
bool http_follow_location; /* follow HTTP redirects */
bool http_transfer_encoding; /* request compressed HTTP transfer-encoding */
- bool http_disable_hostname_check_before_authentication;
+ bool allow_auth_to_other_hosts;
bool include_header; /* include received protocol headers in data output */
bool http_set_referer; /* is a custom referer used */
bool http_auto_referer; /* set "correct" referer when following location: */
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 6e2f402..870d0da 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -55,7 +55,7 @@ test280 test281 test282 test283 test284 test285 test286 test287 test288 \
test289 test290 test291 test292 test293 test294 test295 test296 test297 \
test298 test299 test300 test301 test302 test303 test304 test305 test306 \
test307 test308 test309 test310 test311 test312 test313 \
- test320 test321 test322 test323 test324 \
+ test317 test318 test320 test321 test322 test323 test324 \
test325 \
test350 test351 test352 test353 test354 \
\
diff --git a/tests/data/test317 b/tests/data/test317
new file mode 100644
index 0000000..c6d8697
--- /dev/null
+++ b/tests/data/test317
@@ -0,0 +1,94 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP proxy
+HTTP Basic auth
+HTTP proxy Basic auth
+followlocation
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 302 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Location: http://goto.second.host.now/3170002
+Content-Length: 8
+Connection: close
+
+contents
+</data>
+<data2>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Content-Length: 9
+
+contents
+</data2>
+
+<datacheck>
+HTTP/1.1 302 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Location: http://goto.second.host.now/3170002
+Content-Length: 8
+Connection: close
+
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Content-Length: 9
+
+contents
+</datacheck>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP with custom Authorization: and redirect to new host
+ </name>
+ <command>
+http://first.host.it.is/we/want/that/page/317 -x %HOSTIP:%HTTPPORT -H "Authorization: s3cr3t" --proxy-user testing:this --location
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET http://first.host.it.is/we/want/that/page/317 HTTP/1.1
+Host: first.host.it.is
+Proxy-Authorization: Basic dGVzdGluZzp0aGlz
+Accept: */*
+Proxy-Connection: Keep-Alive
+Authorization: s3cr3t
+
+GET http://goto.second.host.now/3170002 HTTP/1.1
+Host: goto.second.host.now
+Proxy-Authorization: Basic dGVzdGluZzp0aGlz
+Accept: */*
+Proxy-Connection: Keep-Alive
+
+</protocol>
+</verify>
+</testcase>
diff --git a/tests/data/test318 b/tests/data/test318
new file mode 100644
index 0000000..838d1ba
--- /dev/null
+++ b/tests/data/test318
@@ -0,0 +1,95 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP proxy
+HTTP Basic auth
+HTTP proxy Basic auth
+followlocation
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data>
+HTTP/1.1 302 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Location: http://goto.second.host.now/3180002
+Content-Length: 8
+Connection: close
+
+contents
+</data>
+<data2>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Content-Length: 9
+
+contents
+</data2>
+
+<datacheck>
+HTTP/1.1 302 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Location: http://goto.second.host.now/3180002
+Content-Length: 8
+Connection: close
+
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake swsclose
+Content-Type: text/html
+Funny-head: yesyes
+Content-Length: 9
+
+contents
+</datacheck>
+</reply>
+
+#
+# Client-side
+<client>
+<server>
+http
+</server>
+ <name>
+HTTP with custom Authorization: and redirect to new host
+ </name>
+ <command>
+http://first.host.it.is/we/want/that/page/318 -x %HOSTIP:%HTTPPORT -H "Authorization: s3cr3t" --proxy-user testing:this --location-trusted
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+</strip>
+<protocol>
+GET http://first.host.it.is/we/want/that/page/318 HTTP/1.1
+Host: first.host.it.is
+Proxy-Authorization: Basic dGVzdGluZzp0aGlz
+Accept: */*
+Proxy-Connection: Keep-Alive
+Authorization: s3cr3t
+
+GET http://goto.second.host.now/3180002 HTTP/1.1
+Host: goto.second.host.now
+Proxy-Authorization: Basic dGVzdGluZzp0aGlz
+Accept: */*
+Proxy-Connection: Keep-Alive
+Authorization: s3cr3t
+
+</protocol>
+</verify>
+</testcase>
--
2.13.6

View file

@ -0,0 +1,42 @@
From cbe5cf0d95a0227739bd2126d5fa411d084e1af2 Mon Sep 17 00:00:00 2001
From: Zhouyihai Ding <ddyihai@ddyihai.svl.corp.google.com>
Date: Wed, 10 Jan 2018 10:12:18 -0800
Subject: [PATCH] http2: fix incorrect trailer buffer size
Prior to this change the stored byte count of each trailer was
miscalculated and 1 less than required. It appears any trailer
after the first that was passed to Curl_client_write would be truncated
or corrupted as well as the size. Potentially the size of some
subsequent trailer could be erroneously extracted from the contents of
that trailer, and since that size is used by client write an
out-of-bounds read could occur and cause a crash or be otherwise
processed by client write.
The bug appears to have been born in 0761a51 (precedes 7.49.0).
Closes https://github.com/curl/curl/pull/2231
Upstream-commit: fa3dbb9a147488a2943bda809c66fc497efe06cb
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http2.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/http2.c b/lib/http2.c
index 0e55801..3d7610d 100644
--- a/lib/http2.c
+++ b/lib/http2.c
@@ -926,8 +926,8 @@ static int on_header(nghttp2_session *session, const nghttp2_frame *frame,
if(stream->bodystarted) {
/* This is trailer fields. */
- /* 3 is for ":" and "\r\n". */
- uint32_t n = (uint32_t)(namelen + valuelen + 3);
+ /* 4 is for ": " and "\r\n". */
+ uint32_t n = (uint32_t)(namelen + valuelen + 4);
DEBUGF(infof(data_s, "h2 trailer: %.*s: %.*s\n", namelen, name, valuelen,
value));
--
2.13.6

View file

@ -0,0 +1,41 @@
From fffbdcf516a527482095eac30baa27b78c2dbaa2 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Thu, 8 Mar 2018 10:33:16 +0100
Subject: [PATCH] readwrite: make sure excess reads don't go beyond buffer end
CVE-2018-1000122
Bug: https://curl.haxx.se/docs/adv_2018-b047.html
Detected by OSS-fuzz
Upstream-commit: d52dc4760f6d9ca1937eefa2093058a952465128
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/transfer.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/lib/transfer.c b/lib/transfer.c
index 3537b58..bc3b39b 100644
--- a/lib/transfer.c
+++ b/lib/transfer.c
@@ -788,10 +788,15 @@ static CURLcode readwrite_data(struct Curl_easy *data,
} /* if(!header and data to read) */
- if(conn->handler->readwrite &&
- (excess > 0 && !conn->bits.stream_was_rewound)) {
+ if(conn->handler->readwrite && excess && !conn->bits.stream_was_rewound) {
/* Parse the excess data */
k->str += nread;
+
+ if(&k->str[excess] > &k->buf[data->set.buffer_size]) {
+ /* the excess amount was too excessive(!), make sure
+ it doesn't read out of buffer */
+ excess = &k->buf[data->set.buffer_size] - k->str;
+ }
nread = (ssize_t)excess;
result = conn->handler->readwrite(data, conn, &nread, &readmore);
--
2.14.3

View file

@ -0,0 +1,45 @@
From 1d7bcc866591aba5788dc6c701ef8b564d09e329 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 6 Mar 2018 23:02:16 +0100
Subject: [PATCH] openldap: check ldap_get_attribute_ber() results for NULL
before using
CVE-2018-1000121
Reported-by: Dario Weisser
Bug: https://curl.haxx.se/docs/adv_2018-97a2.html
Upstream-commit: 9889db043393092e9d4b5a42720bba0b3d58deba
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/openldap.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/lib/openldap.c b/lib/openldap.c
index 369309c..d71946d 100644
--- a/lib/openldap.c
+++ b/lib/openldap.c
@@ -445,7 +445,7 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
for(ent = ldap_first_message(li->ld, msg); ent;
ent = ldap_next_message(li->ld, ent)) {
- struct berval bv, *bvals, **bvp = &bvals;
+ struct berval bv, *bvals;
int binary = 0, msgtype;
CURLcode writeerr;
@@ -507,9 +507,9 @@ static ssize_t ldap_recv(struct connectdata *conn, int sockindex, char *buf,
}
data->req.bytecount += bv.bv_len + 5;
- for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp);
- rc == LDAP_SUCCESS;
- rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, bvp)) {
+ for(rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals);
+ (rc == LDAP_SUCCESS) && bvals;
+ rc = ldap_get_attribute_ber(li->ld, ent, ber, &bv, &bvals)) {
int i;
if(bv.bv_val == NULL) break;
--
2.14.3

View file

@ -0,0 +1,302 @@
From 5452fdc5ae93f3571074c591fdf28cdf630796a0 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Tue, 12 Sep 2017 09:29:01 +0200
Subject: [PATCH 1/2] FTP: URL decode path for dir listing in nocwd mode
Reported-by: Zenju on github
Test 244 added to verify
Fixes #1974
Closes #1976
Upstream-commit: ecf21c551fa3426579463abe34b623111b8d487c
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ftp.c | 29 ++++++++++++--------------
tests/data/Makefile.inc | 2 +-
tests/data/test244 | 54 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 68 insertions(+), 17 deletions(-)
create mode 100644 tests/data/test244
diff --git a/lib/ftp.c b/lib/ftp.c
index bcba6bb..fb3a716 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -975,7 +975,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
char *port_start = NULL;
char *port_sep = NULL;
- addr = calloc(addrlen+1, 1);
+ addr = calloc(addrlen + 1, 1);
if(!addr)
return CURLE_OUT_OF_MEMORY;
@@ -1018,7 +1018,7 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
if(ip_end != NULL) {
port_start = strchr(ip_end, ':');
if(port_start) {
- port_min = curlx_ultous(strtoul(port_start+1, NULL, 10));
+ port_min = curlx_ultous(strtoul(port_start + 1, NULL, 10));
port_sep = strchr(port_start, '-');
if(port_sep) {
port_max = curlx_ultous(strtoul(port_sep + 1, NULL, 10));
@@ -1457,25 +1457,22 @@ static CURLcode ftp_state_list(struct connectdata *conn)
then just do LIST (in that case: nothing to do here)
*/
char *cmd, *lstArg, *slashPos;
+ const char *inpath = data->state.path;
lstArg = NULL;
if((data->set.ftp_filemethod == FTPFILE_NOCWD) &&
- data->state.path &&
- data->state.path[0] &&
- strchr(data->state.path, '/')) {
-
- lstArg = strdup(data->state.path);
- if(!lstArg)
- return CURLE_OUT_OF_MEMORY;
+ inpath && inpath[0] && strchr(inpath, '/')) {
+ size_t n = strlen(inpath);
/* Check if path does not end with /, as then we cut off the file part */
- if(lstArg[strlen(lstArg) - 1] != '/') {
-
+ if(inpath[n - 1] != '/') {
/* chop off the file part if format is dir/dir/file */
- slashPos = strrchr(lstArg, '/');
- if(slashPos)
- *(slashPos+1) = '\0';
+ slashPos = strrchr(inpath, '/');
+ n = slashPos - inpath;
}
+ result = Curl_urldecode(data, inpath, n, &lstArg, NULL, FALSE);
+ if(result)
+ return result;
}
cmd = aprintf("%s%s%s",
@@ -3497,7 +3494,7 @@ static CURLcode ftp_range(struct connectdata *conn)
}
else {
/* X-Y */
- data->req.maxdownload = (to-from)+1; /* include last byte */
+ data->req.maxdownload = (to - from) + 1; /* include last byte */
data->state.resume_from = from;
DEBUGF(infof(conn->data, "FTP RANGE from %" CURL_FORMAT_CURL_OFF_T
" getting %" CURL_FORMAT_CURL_OFF_T " bytes\n",
@@ -4196,7 +4193,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
return result;
}
ftpc->dirdepth = 1; /* we consider it to be a single dir */
- filename = slash_pos ? slash_pos+1 : cur_pos; /* rest is file name */
+ filename = slash_pos ? slash_pos + 1 : cur_pos; /* rest is file name */
}
else
filename = cur_pos; /* this is a file name only */
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 870d0da..d95101b 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -47,7 +47,7 @@ test208 test209 test210 test211 test212 test213 test214 test215 test216 \
test217 test218 test219 test220 test221 test222 test223 test224 test225 \
test226 test227 test228 test229 test231 test233 test234 \
test235 test236 test237 test238 test239 test240 test241 test242 test243 \
- test245 test246 test247 test248 test249 test250 test251 test252 \
+test244 test245 test246 test247 test248 test249 test250 test251 test252 \
test253 test254 test255 test256 test257 test258 test259 test260 test261 \
test262 test263 test264 test265 test266 test267 test268 test269 test270 \
test271 test272 test273 test274 test275 test276 test277 test278 test279 \
diff --git a/tests/data/test244 b/tests/data/test244
new file mode 100644
index 0000000..8ce4b63
--- /dev/null
+++ b/tests/data/test244
@@ -0,0 +1,54 @@
+<testcase>
+<info>
+<keywords>
+FTP
+PASV
+CWD
+--ftp-method
+nocwd
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+<data mode="text">
+total 20
+drwxr-xr-x 8 98 98 512 Oct 22 13:06 .
+drwxr-xr-x 8 98 98 512 Oct 22 13:06 ..
+drwxr-xr-x 2 98 98 512 May 2 1996 .NeXT
+-r--r--r-- 1 0 1 35 Jul 16 1996 README
+lrwxrwxrwx 1 0 1 7 Dec 9 1999 bin -> usr/bin
+dr-xr-xr-x 2 0 1 512 Oct 1 1997 dev
+drwxrwxrwx 2 98 98 512 May 29 16:04 download.html
+dr-xr-xr-x 2 0 1 512 Nov 30 1995 etc
+drwxrwxrwx 2 98 1 512 Oct 30 14:33 pub
+dr-xr-xr-x 5 0 1 512 Oct 1 1997 usr
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+ftp
+</server>
+ <name>
+FTP dir listing with nocwd and URL encoded path
+ </name>
+ <command>
+--ftp-method nocwd ftp://%HOSTIP:%FTPPORT/fir%23t/th%69rd/244/
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER anonymous
+PASS ftp@example.com
+PWD
+EPSV
+TYPE A
+LIST fir#t/third/244/
+QUIT
+</protocol>
+</verify>
+</testcase>
--
2.14.3
From 9534442aae1da4e6cf2ce815e47dbcd82695c3d4 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Wed, 31 Jan 2018 08:40:11 +0100
Subject: [PATCH 2/2] FTP: reject path components with control codes
Refuse to operate when given path components featuring byte values lower
than 32.
Previously, inserting a %00 sequence early in the directory part when
using the 'singlecwd' ftp method could make curl write a zero byte
outside of the allocated buffer.
Test case 340 verifies.
CVE-2018-1000120
Reported-by: Duy Phan Thanh
Bug: https://curl.haxx.se/docs/adv_2018-9cd6.html
Upstream-commit: 535432c0adb62fe167ec09621500470b6fa4eb0f
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/ftp.c | 8 ++++----
tests/data/Makefile.inc | 3 +++
tests/data/test340 | 40 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 47 insertions(+), 4 deletions(-)
create mode 100644 tests/data/test340
diff --git a/lib/ftp.c b/lib/ftp.c
index fb3a716..268efdd 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -1470,7 +1470,7 @@ static CURLcode ftp_state_list(struct connectdata *conn)
slashPos = strrchr(inpath, '/');
n = slashPos - inpath;
}
- result = Curl_urldecode(data, inpath, n, &lstArg, NULL, FALSE);
+ result = Curl_urldecode(data, inpath, n, &lstArg, NULL, TRUE);
if(result)
return result;
}
@@ -3183,7 +3183,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
if(!result)
/* get the "raw" path */
- result = Curl_urldecode(data, path_to_use, 0, &path, NULL, FALSE);
+ result = Curl_urldecode(data, path_to_use, 0, &path, NULL, TRUE);
if(result) {
/* We can limp along anyway (and should try to since we may already be in
* the error path) */
@@ -4187,7 +4187,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
result = Curl_urldecode(conn->data, slash_pos ? cur_pos : "/",
slash_pos ? dirlen : 1,
&ftpc->dirs[0], NULL,
- FALSE);
+ TRUE);
if(result) {
freedirs(ftpc);
return result;
@@ -4294,7 +4294,7 @@ CURLcode ftp_parse_url_path(struct connectdata *conn)
size_t dlen;
char *path;
CURLcode result =
- Curl_urldecode(conn->data, data->state.path, 0, &path, &dlen, FALSE);
+ Curl_urldecode(conn->data, data->state.path, 0, &path, &dlen, TRUE);
if(result) {
freedirs(ftpc);
return result;
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index d95101b..af41634 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -57,6 +57,9 @@ test298 test299 test300 test301 test302 test303 test304 test305 test306 \
test307 test308 test309 test310 test311 test312 test313 \
test317 test318 test320 test321 test322 test323 test324 \
test325 \
+\
+test340 \
+\
test350 test351 test352 test353 test354 \
\
test400 test401 test402 test403 test404 test405 test406 test407 test408 \
diff --git a/tests/data/test340 b/tests/data/test340
new file mode 100644
index 0000000..d834d76
--- /dev/null
+++ b/tests/data/test340
@@ -0,0 +1,40 @@
+<testcase>
+<info>
+<keywords>
+FTP
+PASV
+CWD
+--ftp-method
+singlecwd
+</keywords>
+</info>
+#
+# Server-side
+<reply>
+</reply>
+
+# Client-side
+<client>
+<server>
+ftp
+</server>
+ <name>
+FTP using %00 in path with singlecwd
+ </name>
+ <command>
+--ftp-method singlecwd ftp://%HOSTIP:%FTPPORT/%00first/second/third/340
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<protocol>
+USER anonymous
+PASS ftp@example.com
+PWD
+</protocol>
+<errorcode>
+3
+</errorcode>
+</verify>
+</testcase>
--
2.14.3

View file

@ -0,0 +1,48 @@
From 5815730864a2010872840bae24797983e892eb90 Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sat, 24 Mar 2018 23:47:41 +0100
Subject: [PATCH 1/2] http: restore buffer pointer when bad response-line is
parsed
... leaving the k->str could lead to buffer over-reads later on.
CVE: CVE-2018-1000301
Assisted-by: Max Dymond
Detected by OSS-Fuzz.
Bug: https://curl.haxx.se/docs/adv_2018-b138.html
Bug: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=7105
Upstream-commit: 8c7b3737d29ed5c0575bf592063de8a51450812d
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/http.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/lib/http.c b/lib/http.c
index 841f6cc..dc10f5f 100644
--- a/lib/http.c
+++ b/lib/http.c
@@ -2944,6 +2944,8 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
{
CURLcode result;
struct SingleRequest *k = &data->req;
+ ssize_t onread = *nread;
+ char *ostr = k->str;
/* header line within buffer loop */
do {
@@ -3008,7 +3010,9 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
else {
/* this was all we read so it's all a bad header */
k->badheader = HEADER_ALLBAD;
- *nread = (ssize_t)rest_length;
+ *nread = onread;
+ k->str = ostr;
+ return CURLE_OK;
}
break;
}
--
2.14.3

View file

@ -0,0 +1,39 @@
From 9b757a9a431f6859807d9f6e697cc2d2a120098d Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Fri, 23 Mar 2018 23:30:04 +0100
Subject: [PATCH 2/2] pingpong: fix response cache memcpy overflow
Response data for a handle with a large buffer might be cached and then
used with the "closure" handle when it has a smaller buffer and then the
larger cache will be copied and overflow the new smaller heap based
buffer.
Reported-by: Dario Weisser
CVE: CVE-2018-1000300
Bug: https://curl.haxx.se/docs/adv_2018-82c2.html
Upstream-commit: 583b42cb3b809b1bf597af160468ccba728c2248
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/pingpong.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/lib/pingpong.c b/lib/pingpong.c
index 438856a..ad370ee 100644
--- a/lib/pingpong.c
+++ b/lib/pingpong.c
@@ -297,7 +297,10 @@ CURLcode Curl_pp_readresp(curl_socket_t sockfd,
* it would have been populated with something of size int to begin
* with, even though its datatype may be larger than an int.
*/
- DEBUGASSERT((ptr+pp->cache_size) <= (buf+data->set.buffer_size+1));
+ if((ptr + pp->cache_size) > (buf + data->set.buffer_size + 1)) {
+ failf(data, "cached response data too big to handle");
+ return CURLE_RECV_ERROR;
+ }
memcpy(ptr, pp->cache, pp->cache_size);
gotbytes = (ssize_t)pp->cache_size;
free(pp->cache); /* free the cache */
--
2.14.3

View file

@ -0,0 +1,225 @@
From 1b9c12b59b582d5366d9a11198631be54c94e440 Mon Sep 17 00:00:00 2001
From: Anderson Toshiyuki Sasaki <ansasaki@redhat.com>
Date: Mon, 19 Feb 2018 14:31:06 +0100
Subject: [PATCH] ssl: set engine implicitly when a PKCS#11 URI is provided
This allows the use of PKCS#11 URI for certificates and keys without
setting the corresponding type as "ENG" and the engine as "pkcs11"
explicitly. If a PKCS#11 URI is provided for certificate, key,
proxy_certificate or proxy_key, the corresponding type is set as "ENG"
if not provided and the engine is set to "pkcs11" if not provided.
Acked-by: Nikos Mavrogiannopoulos
Closes #2333
Upstream-commit: 298d2565e2a2f06a859b7f5a1cc24ba7c87a8ce2
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
docs/cmdline-opts/cert.d | 7 ++++++
docs/cmdline-opts/key.d | 7 ++++++
lib/vtls/openssl.c | 38 ++++++++++++++++++++++++++++
src/tool_getparam.c | 2 +-
src/tool_operate.c | 53 ++++++++++++++++++++++++++++++++++++++++
tests/unit/unit1394.c | 3 +++
6 files changed, 109 insertions(+), 1 deletion(-)
diff --git a/docs/cmdline-opts/cert.d b/docs/cmdline-opts/cert.d
index 0cd5d53..ae6fe2f 100644
--- a/docs/cmdline-opts/cert.d
+++ b/docs/cmdline-opts/cert.d
@@ -23,6 +23,13 @@ nickname contains ":", it needs to be preceded by "\\" so that it is not
recognized as password delimiter. If the nickname contains "\\", it needs to
be escaped as "\\\\" so that it is not recognized as an escape character.
+If curl is built against OpenSSL library, and the engine pkcs11 is available,
+then a PKCS#11 URI (RFC 7512) can be used to specify a certificate located in
+a PKCS#11 device. A string beginning with "pkcs11:" will be interpreted as a
+PKCS#11 URI. If a PKCS#11 URI is provided, then the --engine option will be set
+as "pkcs11" if none was provided and the --cert-type option will be set as
+"ENG" if none was provided.
+
(iOS and macOS only) If curl is built against Secure Transport, then the
certificate string can either be the name of a certificate/private key in the
system or user keychain, or the path to a PKCS#12-encoded certificate and
diff --git a/docs/cmdline-opts/key.d b/docs/cmdline-opts/key.d
index fbf583a..4877b42 100644
--- a/docs/cmdline-opts/key.d
+++ b/docs/cmdline-opts/key.d
@@ -7,4 +7,11 @@ Private key file name. Allows you to provide your private key in this separate
file. For SSH, if not specified, curl tries the following candidates in order:
'~/.ssh/id_rsa', '~/.ssh/id_dsa', './id_rsa', './id_dsa'.
+If curl is built against OpenSSL library, and the engine pkcs11 is available,
+then a PKCS#11 URI (RFC 7512) can be used to specify a private key located in a
+PKCS#11 device. A string beginning with "pkcs11:" will be interpreted as a
+PKCS#11 URI. If a PKCS#11 URI is provided, then the --engine option will be set
+as "pkcs11" if none was provided and the --key-type option will be set as
+"ENG" if none was provided.
+
If this option is used several times, the last one will be used.
diff --git a/lib/vtls/openssl.c b/lib/vtls/openssl.c
index 8c1d5a8..82c3c86 100644
--- a/lib/vtls/openssl.c
+++ b/lib/vtls/openssl.c
@@ -380,8 +380,25 @@ static int ssl_ui_writer(UI *ui, UI_STRING *uis)
}
return (UI_method_get_writer(UI_OpenSSL()))(ui, uis);
}
+
+/*
+ * Check if a given string is a PKCS#11 URI
+ */
+static bool is_pkcs11_uri(const char *string)
+{
+ if(strncasecompare(string, "pkcs11:", 7)) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
#endif
+CURLcode Curl_ossl_set_engine(struct Curl_easy *data,
+ const char *engine);
+
static
int cert_stuff(struct connectdata *conn,
SSL_CTX* ctx,
@@ -443,6 +460,16 @@ int cert_stuff(struct connectdata *conn,
case SSL_FILETYPE_ENGINE:
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(ENGINE_CTRL_GET_CMD_FROM_NAME)
{
+ /* Implicitly use pkcs11 engine if none was provided and the
+ * cert_file is a PKCS#11 URI */
+ if(!data->state.engine) {
+ if(is_pkcs11_uri(cert_file)) {
+ if(Curl_ossl_set_engine(data, "pkcs11") != CURLE_OK) {
+ return 0;
+ }
+ }
+ }
+
if(data->state.engine) {
const char *cmd_name = "LOAD_CERT_CTRL";
struct {
@@ -614,6 +641,17 @@ int cert_stuff(struct connectdata *conn,
#ifdef HAVE_OPENSSL_ENGINE_H
{ /* XXXX still needs some work */
EVP_PKEY *priv_key = NULL;
+
+ /* Implicitly use pkcs11 engine if none was provided and the
+ * key_file is a PKCS#11 URI */
+ if(!data->state.engine) {
+ if(is_pkcs11_uri(key_file)) {
+ if(Curl_ossl_set_engine(data, "pkcs11") != CURLE_OK) {
+ return 0;
+ }
+ }
+ }
+
if(data->state.engine) {
UI_METHOD *ui_method =
UI_create_method((char *)"curl user interface");
diff --git a/src/tool_getparam.c b/src/tool_getparam.c
index b7ee519..7399757 100644
--- a/src/tool_getparam.c
+++ b/src/tool_getparam.c
@@ -333,7 +333,7 @@ void parse_cert_parameter(const char *cert_parameter,
* looks like a RFC7512 PKCS#11 URI which can be used as-is.
* Also if cert_parameter contains no colon nor backslash, this
* means no passphrase was given and no characters escaped */
- if(!strncmp(cert_parameter, "pkcs11:", 7) ||
+ if(curl_strnequal(cert_parameter, "pkcs11:", 7) ||
!strpbrk(cert_parameter, ":\\")) {
*certname = strdup(cert_parameter);
return;
diff --git a/src/tool_operate.c b/src/tool_operate.c
index 1e8d007..f041427 100644
--- a/src/tool_operate.c
+++ b/src/tool_operate.c
@@ -127,6 +127,19 @@ static bool is_fatal_error(CURLcode code)
return FALSE;
}
+/*
+ * Check if a given string is a PKCS#11 URI
+ */
+static bool is_pkcs11_uri(const char *string)
+{
+ if(curl_strnequal(string, "pkcs11:", 7)) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
#ifdef __VMS
/*
* get_vms_file_size does what it takes to get the real size of the file
@@ -1136,6 +1149,46 @@ static CURLcode operate_do(struct GlobalConfig *global,
my_setopt_str(curl, CURLOPT_PINNEDPUBLICKEY, config->pinnedpubkey);
if(curlinfo->features & CURL_VERSION_SSL) {
+ /* Check if config->cert is a PKCS#11 URI and set the
+ * config->cert_type if necessary */
+ if(config->cert) {
+ if(!config->cert_type) {
+ if(is_pkcs11_uri(config->cert)) {
+ config->cert_type = strdup("ENG");
+ }
+ }
+ }
+
+ /* Check if config->key is a PKCS#11 URI and set the
+ * config->key_type if necessary */
+ if(config->key) {
+ if(!config->key_type) {
+ if(is_pkcs11_uri(config->key)) {
+ config->key_type = strdup("ENG");
+ }
+ }
+ }
+
+ /* Check if config->proxy_cert is a PKCS#11 URI and set the
+ * config->proxy_type if necessary */
+ if(config->proxy_cert) {
+ if(!config->proxy_cert_type) {
+ if(is_pkcs11_uri(config->proxy_cert)) {
+ config->proxy_cert_type = strdup("ENG");
+ }
+ }
+ }
+
+ /* Check if config->proxy_key is a PKCS#11 URI and set the
+ * config->proxy_key_type if necessary */
+ if(config->proxy_key) {
+ if(!config->proxy_key_type) {
+ if(is_pkcs11_uri(config->proxy_key)) {
+ config->proxy_key_type = strdup("ENG");
+ }
+ }
+ }
+
my_setopt_str(curl, CURLOPT_SSLCERT, config->cert);
my_setopt_str(curl, CURLOPT_PROXY_SSLCERT, config->proxy_cert);
my_setopt_str(curl, CURLOPT_SSLCERTTYPE, config->cert_type);
diff --git a/tests/unit/unit1394.c b/tests/unit/unit1394.c
index 667991d..010f052 100644
--- a/tests/unit/unit1394.c
+++ b/tests/unit/unit1394.c
@@ -56,6 +56,9 @@ UNITTEST_START
"foo:bar\\\\", "foo", "bar\\\\",
"foo:bar:", "foo", "bar:",
"foo\\::bar\\:", "foo:", "bar\\:",
+ "pkcs11:foobar", "pkcs11:foobar", NULL,
+ "PKCS11:foobar", "PKCS11:foobar", NULL,
+ "PkCs11:foobar", "PkCs11:foobar", NULL,
#ifdef WIN32
"c:\\foo:bar:baz", "c:\\foo", "bar:baz",
"c:\\foo\\:bar:baz", "c:\\foo:bar", "baz",
--
2.17.1

View file

@ -0,0 +1,144 @@
From bde648303aea273a688e65a1caafdd94b7b0123e Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Sat, 4 Nov 2017 16:42:21 +0100
Subject: [PATCH 1/3] ntlm: avoid malloc(0) for zero length passwords
It triggers an assert() when built with memdebug since malloc(0) may
return NULL *or* a valid pointer.
Detected by OSS-Fuzz: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=4054
Assisted-by: Max Dymond
Closes #2054
Upstream-commit: 685ef130575cdcf63fe9547757d88a49a40ef281
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/curl_ntlm_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index eb44f97..1c7b7b0 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -538,7 +538,7 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
unsigned char *ntbuffer /* 21 bytes */)
{
size_t len = strlen(password);
- unsigned char *pw = malloc(len * 2);
+ unsigned char *pw = len ? malloc(len * 2) : strdup("");
CURLcode result;
if(!pw)
return CURLE_OUT_OF_MEMORY;
--
2.17.1
From 2a23557fe8ab3316c5f961f79e50a03ab54cb07f Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 27 Nov 2017 10:40:31 +0100
Subject: [PATCH 2/3] curl_ntlm_core.c: use the limits.h's SIZE_T_MAX if
provided
Upstream-commit: 014887c50ab58bf35b1231dbfe11197fe41d59cc
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/curl_ntlm_core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index 1c7b7b0..9fc3e8d 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -622,11 +622,14 @@ CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
return CURLE_OK;
}
+#ifndef SIZE_T_MAX
+/* some limits.h headers have this defined, some don't */
#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4)
#define SIZE_T_MAX 18446744073709551615U
#else
#define SIZE_T_MAX 4294967295U
#endif
+#endif
/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
* (uppercase UserName + Domain) as the data
--
2.17.1
From 405a7e855f1dfcc03d01e441cc53db1980c4454d Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <daniel@haxx.se>
Date: Mon, 13 Aug 2018 10:35:52 +0200
Subject: [PATCH 3/3] Curl_ntlm_core_mk_nt_hash: return error on too long
password
... since it would cause an integer overflow if longer than (max size_t
/ 2).
This is CVE-2018-14618
Bug: https://curl.haxx.se/docs/CVE-2018-14618.html
Closes #2756
Reported-by: Zhaoyang Wu
Upstream-commit: 57d299a499155d4b327e341c6024e293b0418243
Signed-off-by: Kamil Dudka <kdudka@redhat.com>
---
lib/curl_ntlm_core.c | 23 +++++++++++++----------
1 file changed, 13 insertions(+), 10 deletions(-)
diff --git a/lib/curl_ntlm_core.c b/lib/curl_ntlm_core.c
index 9fc3e8d..34d8b67 100644
--- a/lib/curl_ntlm_core.c
+++ b/lib/curl_ntlm_core.c
@@ -124,6 +124,15 @@
#define NTLMv2_BLOB_SIGNATURE "\x01\x01\x00\x00"
#define NTLMv2_BLOB_LEN (44 -16 + ntlm->target_info_len + 4)
+#ifndef SIZE_T_MAX
+/* some limits.h headers have this defined, some don't */
+#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4)
+#define SIZE_T_MAX 18446744073709551615U
+#else
+#define SIZE_T_MAX 4294967295U
+#endif
+#endif
+
/*
* Turns a 56-bit key into being 64-bit wide.
*/
@@ -538,8 +547,11 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
unsigned char *ntbuffer /* 21 bytes */)
{
size_t len = strlen(password);
- unsigned char *pw = len ? malloc(len * 2) : strdup("");
+ unsigned char *pw;
CURLcode result;
+ if(len > SIZE_T_MAX/2) /* avoid integer overflow */
+ return CURLE_OUT_OF_MEMORY;
+ pw = len ? malloc(len * 2) : strdup("");
if(!pw)
return CURLE_OUT_OF_MEMORY;
@@ -622,15 +634,6 @@ CURLcode Curl_hmac_md5(const unsigned char *key, unsigned int keylen,
return CURLE_OK;
}
-#ifndef SIZE_T_MAX
-/* some limits.h headers have this defined, some don't */
-#if defined(SIZEOF_SIZE_T) && (SIZEOF_SIZE_T > 4)
-#define SIZE_T_MAX 18446744073709551615U
-#else
-#define SIZE_T_MAX 4294967295U
-#endif
-#endif
-
/* This creates the NTLMv2 hash by using NTLM hash as the key and Unicode
* (uppercase UserName + Domain) as the data
*/
--
2.17.1

View file

@ -1,7 +1,7 @@
Summary: A utility for getting files from remote servers (FTP, HTTP, and others)
Name: curl
Version: 7.55.1
Release: 5%{?dist}
Release: 14%{?dist}
License: MIT
Group: Applications/Internet
Source: https://curl.haxx.se/download/%{name}-%{version}.tar.xz
@ -12,6 +12,48 @@ Patch1: 0001-curl-7.55.1-zsh-completion.patch
# http: Don't wait on CONNECT when there is no proxy (#1485702)
Patch2: 0002-curl-7.55.1-proxy-connect.patch
# http2: handle GOAWAY properly (#1585797)
Patch4: 0004-curl-7.59.0-http2-GOAWAY.patch
# fix out of bounds read in FTP PWD response parser (CVE-2017-1000254)
Patch5: 0005-curl-7.55.1-CVE-2017-1000254.patch
# fix buffer overflow while processing IMAP FETCH response (CVE-2017-1000257)
Patch6: 0006-curl-7.55.1-CVE-2017-1000257.patch
# fix FTP wildcard out of bounds read (CVE-2017-8817)
Patch7: 0007-curl-7.55.1-CVE-2017-8817.patch
# fix NTLM buffer overflow via integer overflow (CVE-2017-8816)
Patch8: 0008-curl-7.55.1-CVE-2017-8816.patch
# http: prevent custom Authorization headers in redirects (CVE-2018-1000007)
Patch9: 0009-curl-7.55.1-CVE-2018-1000007.patch
# http2: fix incorrect trailer buffer size (CVE-2018-1000005)
Patch10: 0010-curl-7.55.1-CVE-2018-1000005.patch
# fix RTSP RTP buffer over-read (CVE-2018-1000122)
Patch16: 0016-curl-7.55.1-CVE-2018-1000122.patch
# fix LDAP NULL pointer dereference (CVE-2018-1000121)
Patch17: 0017-curl-7.55.1-CVE-2018-1000121.patch
# fix FTP path trickery leads to NIL byte out of bounds write (CVE-2018-1000120)
Patch18: 0018-curl-7.55.1-CVE-2018-1000120.patch
# fix RTSP bad headers buffer over-read (CVE-2018-1000301)
Patch19: 0019-curl-7.55.1-CVE-2018-1000301.patch
# fix FTP shutdown response buffer overflow (CVE-2018-1000300)
Patch20: 0020-curl-7.55.1-CVE-2018-1000300.patch
# ssl: set engine implicitly when a PKCS#11 URI is provided (#1219544)
Patch21: 0021-curl-7.55.1-pkcs11.patch
# fix NTLM password overflow via integer overflow (CVE-2018-14618)
Patch22: 0022-curl-7.55.1-CVE-2018-14618.patch
# patch making libcurl multilib ready
Patch101: 0101-curl-7.32.0-multilib.patch
@ -28,7 +70,7 @@ Provides: curl-full = %{version}-%{release}
Provides: webclient
URL: https://curl.haxx.se/
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(id -nu)
#BuildRequires: automake
BuildRequires: automake
BuildRequires: groff
BuildRequires: krb5-devel
BuildRequires: libidn2-devel
@ -160,6 +202,20 @@ be installed.
# upstream patches
%patch1 -p1
%patch2 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%patch9 -p1
%patch10 -p1
%patch16 -p1
%patch17 -p1
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
# Fedora patches
%patch101 -p1
@ -168,8 +224,8 @@ be installed.
%patch104 -p1
# regenerate Makefile.in files
#aclocal -I m4
#automake
aclocal -I m4
automake
# disable test 1112 (#565305) and test 1801
# <https://github.com/bagder/curl/commit/21e82bd6#commitcomment-12226582>
@ -314,6 +370,38 @@ rm -f ${RPM_BUILD_ROOT}%{_libdir}/libcurl.la
%{_libdir}/libcurl.so.[0-9].[0-9].[0-9].minimal
%changelog
* Wed Sep 05 2018 Kamil Dudka <kdudka@redhat.com> - 7.55.1-14
- fix NTLM password overflow via integer overflow (CVE-2018-14618)
* Thu Aug 09 2018 Kamil Dudka <kdudka@redhat.com> - 7.55.1-13
- ssl: set engine implicitly when a PKCS#11 URI is provided (#1219544)
* Tue Jun 05 2018 Kamil Dudka <kdudka@redhat.com> - 7.55.1-12
- http2: handle GOAWAY properly (#1585797)
* Fri May 18 2018 Kamil Dudka <kdudka@redhat.com> - 7.55.1-11
- fix FTP shutdown response buffer overflow (CVE-2018-1000300)
- fix RTSP bad headers buffer over-read (CVE-2018-1000301)
* Wed Mar 14 2018 Kamil Dudka <kdudka@redhat.com> - 7.55.1-10
- fix FTP path trickery leads to NIL byte out of bounds write (CVE-2018-1000120)
- fix LDAP NULL pointer dereference (CVE-2018-1000121)
- fix RTSP RTP buffer over-read (CVE-2018-1000122)
* Wed Jan 24 2018 Kamil Dudka <kdudka@redhat.com> - 7.55.1-9
- http2: fix incorrect trailer buffer size (CVE-2018-1000005)
- http: prevent custom Authorization headers in redirects (CVE-2018-1000007)
* Thu Nov 30 2017 Kamil Dudka <kdudka@redhat.com> - 7.55.1-8
- fix NTLM buffer overflow via integer overflow (CVE-2017-8816)
- fix FTP wildcard out of bounds read (CVE-2017-8817)
* Mon Oct 23 2017 Kamil Dudka <kdudka@redhat.com> - 7.55.1-7
- fix buffer overflow while processing IMAP FETCH response (CVE-2017-1000257)
* Wed Oct 04 2017 Kamil Dudka <kdudka@redhat.com> - 7.55.1-6
- fix out of bounds read in FTP PWD response parser (CVE-2017-1000254)
* Mon Aug 28 2017 Kamil Dudka <kdudka@redhat.com> - 7.55.1-5
- apply the patch for the previous commit and fix its name (#1485702)