Commit 025b11b1 authored by Sergey Lyubka's avatar Sergey Lyubka

Fixed buffer overflow in put_dir()

parent 27983c53
...@@ -3029,26 +3029,31 @@ static int put_dir(const char *path) { ...@@ -3029,26 +3029,31 @@ static int put_dir(const char *path) {
char buf[PATH_MAX]; char buf[PATH_MAX];
const char *s, *p; const char *s, *p;
struct mgstat st; struct mgstat st;
size_t len; int len, res = 1;
for (s = p = path + 2; (p = strchr(s, '/')) != NULL; s = ++p) { for (s = p = path + 2; (p = strchr(s, DIRSEP)) != NULL; s = ++p) {
len = p - path; len = p - path;
assert(len < sizeof(buf)); if (len >= (int) sizeof(buf)) {
(void) memcpy(buf, path, len); res = -1;
break;
}
memcpy(buf, path, len);
buf[len] = '\0'; buf[len] = '\0';
// Try to create intermediate directory // Try to create intermediate directory
DEBUG_TRACE(("mkdir(%s)", buf));
if (mg_stat(buf, &st) == -1 && mg_mkdir(buf, 0755) != 0) { if (mg_stat(buf, &st) == -1 && mg_mkdir(buf, 0755) != 0) {
return -1; res = -1;
break;
} }
// Is path itself a directory? // Is path itself a directory?
if (p[1] == '\0') { if (p[1] == '\0') {
return 0; res = 0;
} }
} }
return 1; return res;
} }
static void put_file(struct mg_connection *conn, const char *path) { static void put_file(struct mg_connection *conn, const char *path) {
...@@ -3245,7 +3250,7 @@ static void handle_request(struct mg_connection *conn) { ...@@ -3245,7 +3250,7 @@ static void handle_request(struct mg_connection *conn) {
* conn->request_info.query_string++ = '\0'; * conn->request_info.query_string++ = '\0';
} }
uri_len = strlen(ri->uri); uri_len = strlen(ri->uri);
(void) url_decode(ri->uri, (size_t)uri_len, ri->uri, (size_t)(uri_len + 1), 0); url_decode(ri->uri, (size_t)uri_len, ri->uri, (size_t)(uri_len + 1), 0);
remove_double_dots_and_double_slashes(ri->uri); remove_double_dots_and_double_slashes(ri->uri);
convert_uri_to_file_name(conn, ri->uri, path, sizeof(path)); convert_uri_to_file_name(conn, ri->uri, path, sizeof(path));
......
...@@ -24,8 +24,8 @@ my $embed_exe = '.' . $dir_separator . 'embed'; ...@@ -24,8 +24,8 @@ my $embed_exe = '.' . $dir_separator . 'embed';
my $unit_test_exe = '.' . $dir_separator . 'unit_test'; my $unit_test_exe = '.' . $dir_separator . 'unit_test';
my $exit_code = 0; my $exit_code = 0;
my @files_to_delete = ('debug.log', 'access.log', $config, "$root/put.txt", my @files_to_delete = ('debug.log', 'access.log', $config, "$root/a/put.txt",
"$root/a+.txt", "$root/.htpasswd", "$root/binary_file", "$root/a+.txt", "$root/.htpasswd", "$root/binary_file", "$root/a",
$embed_exe, $unit_test_exe); $embed_exe, $unit_test_exe);
END { END {
...@@ -395,20 +395,20 @@ sub do_PUT_test { ...@@ -395,20 +395,20 @@ sub do_PUT_test {
"response=896327350763836180c61d87578037d9, qop=auth, ". "response=896327350763836180c61d87578037d9, qop=auth, ".
"nc=00000002, cnonce=53eddd3be4e26a98\n"; "nc=00000002, cnonce=53eddd3be4e26a98\n";
o("PUT /put.txt HTTP/1.0\nContent-Length: 7\n$auth_header\n1234567", o("PUT /a/put.txt HTTP/1.0\nContent-Length: 7\n$auth_header\n1234567",
"HTTP/1.1 201 OK", 'PUT file, status 201'); "HTTP/1.1 201 OK", 'PUT file, status 201');
fail("PUT content mismatch") fail("PUT content mismatch")
unless read_file("$root/put.txt") eq '1234567'; unless read_file("$root/a/put.txt") eq '1234567';
o("PUT /put.txt HTTP/1.0\nContent-Length: 4\n$auth_header\nabcd", o("PUT /a/put.txt HTTP/1.0\nContent-Length: 4\n$auth_header\nabcd",
"HTTP/1.1 200 OK", 'PUT file, status 200'); "HTTP/1.1 200 OK", 'PUT file, status 200');
fail("PUT content mismatch") fail("PUT content mismatch")
unless read_file("$root/put.txt") eq 'abcd'; unless read_file("$root/a/put.txt") eq 'abcd';
o("PUT /put.txt HTTP/1.0\n$auth_header\nabcd", o("PUT /a/put.txt HTTP/1.0\n$auth_header\nabcd",
"HTTP/1.1 411 Length Required", 'PUT 411 error'); "HTTP/1.1 411 Length Required", 'PUT 411 error');
o("PUT /put.txt HTTP/1.0\nExpect: blah\nContent-Length: 1\n". o("PUT /a/put.txt HTTP/1.0\nExpect: blah\nContent-Length: 1\n".
"$auth_header\nabcd", "$auth_header\nabcd",
"HTTP/1.1 417 Expectation Failed", 'PUT 417 error'); "HTTP/1.1 417 Expectation Failed", 'PUT 417 error');
o("PUT /put.txt HTTP/1.0\nExpect: 100-continue\nContent-Length: 4\n". o("PUT /a/put.txt HTTP/1.0\nExpect: 100-continue\nContent-Length: 4\n".
"$auth_header\nabcd", "$auth_header\nabcd",
"HTTP/1.1 100 Continue.+HTTP/1.1 200", 'PUT 100-Continue'); "HTTP/1.1 100 Continue.+HTTP/1.1 200", 'PUT 100-Continue');
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment