summaryrefslogtreecommitdiff
path: root/lib/url.c
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2017-06-07 00:21:04 +0200
committerDaniel Stenberg <daniel@haxx.se>2017-06-13 09:34:20 +0200
commit5d7952f52e410e1d4a8ff1965e5cc6fc1bde86aa (patch)
treecca6f8b5b78130c543ecfd34b14560d1da165019 /lib/url.c
parent5fa028e508056e3569beb5698e3f52e45fea94da (diff)
downloadcurl-5d7952f52e410e1d4a8ff1965e5cc6fc1bde86aa.tar.gz
url: fix buffer overwrite with file protocol (CVE-2017-9502)
Bug: https://github.com/curl/curl/issues/1540 Advisory: https://curl.haxx.se/docs/adv_20170614.html Assisted-by: Ray Satiro Reported-by: Marcel Raad
Diffstat (limited to 'lib/url.c')
-rw-r--r--lib/url.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/lib/url.c b/lib/url.c
index 84822d9bc..87446dbca 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -4466,6 +4466,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
#endif
protop = "file"; /* protocol string */
+ *prot_missing = !url_has_scheme;
}
else {
/* clear path */
@@ -4629,14 +4630,30 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data,
size_t plen = strlen(path); /* new path, should be 1 byte longer than
the original */
- size_t urllen = strlen(data->change.url); /* original URL length */
-
size_t prefixlen = strlen(conn->host.name);
- if(!*prot_missing)
- prefixlen += strlen(protop) + strlen("://");
+ if(!*prot_missing) {
+ size_t protolen = strlen(protop);
+
+ if(curl_strnequal(protop, data->change.url, protolen))
+ prefixlen += protolen;
+ else {
+ failf(data, "<url> malformed");
+ return CURLE_URL_MALFORMAT;
+ }
+
+ if(curl_strnequal("://", &data->change.url[protolen], 3))
+ prefixlen += 3;
+ /* only file: is allowed to omit one or both slashes */
+ else if(curl_strnequal("file:", data->change.url, 5))
+ prefixlen += 1 + (data->change.url[5] == '/');
+ else {
+ failf(data, "<url> malformed");
+ return CURLE_URL_MALFORMAT;
+ }
+ }
- reurl = malloc(urllen + 2); /* 2 for zerobyte + slash */
+ reurl = malloc(prefixlen + plen + 1);
if(!reurl)
return CURLE_OUT_OF_MEMORY;