aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Stenberg <daniel@haxx.se>2014-09-25 13:44:24 +0200
committerDaniel Stenberg <daniel@haxx.se>2014-09-30 07:37:38 +0200
commit53cbea22310f1509e98f5537ef3a83c6e600629f (patch)
treea184cada60b6d789553e5c686739d0c8cbc01b39
parent46d71e7fd298f8c5d23034a88e856b254ff64253 (diff)
file: reject paths using embedded %00
Mostly because we use C strings and they end at a binary zero so we know we can't open a file name using an embedded binary zero. Reported-by: research@g0blin.co.uk
-rw-r--r--lib/file.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/lib/file.c b/lib/file.c
index 73df42e02..230f1c20d 100644
--- a/lib/file.c
+++ b/lib/file.c
@@ -196,8 +196,9 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
int i;
char *actual_path;
#endif
+ int real_path_len;
- real_path = curl_easy_unescape(data, data->state.path, 0, NULL);
+ real_path = curl_easy_unescape(data, data->state.path, 0, &real_path_len);
if(!real_path)
return CURLE_OUT_OF_MEMORY;
@@ -222,16 +223,23 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
(actual_path[2] == ':' || actual_path[2] == '|')) {
actual_path[2] = ':';
actual_path++;
+ real_path_len--;
}
/* change path separators from '/' to '\\' for DOS, Windows and OS/2 */
- for(i=0; actual_path[i] != '\0'; ++i)
+ for(i=0; i < real_path_len; ++i)
if(actual_path[i] == '/')
actual_path[i] = '\\';
+ else if(!actual_path[i]) /* binary zero */
+ return CURLE_URL_MALFORMAT;
fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
file->path = actual_path;
#else
+ if(memchr(real_path, 0, real_path_len))
+ /* binary zeroes indicate foul play */
+ return CURLE_URL_MALFORMAT;
+
fd = open_readonly(real_path, O_RDONLY);
file->path = real_path;
#endif