diff options
author | Vladimir Homutov <vl@nginx.com> | 2018-12-25 12:59:24 +0300 |
---|---|---|
committer | Vladimir Homutov <vl@nginx.com> | 2018-12-25 12:59:24 +0300 |
commit | 910f330ad0caa49fe901e9426ef00d95d45ba32c (patch) | |
tree | 07fadf71a2edf043d782d70cdb8cead63c3a8712 | |
parent | 8610ddd09240f5e0658e7f74f99a4a29ec413583 (diff) | |
download | nginx-910f330ad0caa49fe901e9426ef00d95d45ba32c.tar.gz nginx-910f330ad0caa49fe901e9426ef00d95d45ba32c.zip |
Autoindex: fixed possible integer overflow on 32-bit systems.
-rw-r--r-- | src/http/modules/ngx_http_autoindex_module.c | 66 |
1 files changed, 42 insertions, 24 deletions
diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c index 30fd601ef..082bcb5e6 100644 --- a/src/http/modules/ngx_http_autoindex_module.c +++ b/src/http/modules/ngx_http_autoindex_module.c @@ -434,7 +434,7 @@ ngx_http_autoindex_html(ngx_http_request_t *r, ngx_array_t *entries) { u_char *last, scale; off_t length; - size_t len, char_len, escape_html; + size_t len, entry_len, char_len, escape_html; ngx_tm_t tm; ngx_buf_t *b; ngx_int_t size; @@ -499,17 +499,23 @@ ngx_http_autoindex_html(ngx_http_request_t *r, ngx_array_t *entries) entry[i].utf_len = entry[i].name.len; } - len += sizeof("<a href=\"") - 1 - + entry[i].name.len + entry[i].escape - + 1 /* 1 is for "/" */ - + sizeof("\">") - 1 - + entry[i].name.len - entry[i].utf_len - + entry[i].escape_html - + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof(">") - 2 - + sizeof("</a>") - 1 - + sizeof(" 28-Sep-1970 12:00 ") - 1 - + 20 /* the file size */ - + 2; + entry_len = sizeof("<a href=\"") - 1 + + entry[i].name.len + entry[i].escape + + 1 /* 1 is for "/" */ + + sizeof("\">") - 1 + + entry[i].name.len - entry[i].utf_len + + entry[i].escape_html + + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof(">") - 2 + + sizeof("</a>") - 1 + + sizeof(" 28-Sep-1970 12:00 ") - 1 + + 20 /* the file size */ + + 2; + + if (len > NGX_MAX_SIZE_T_VALUE - entry_len) { + return NULL; + } + + len += entry_len; } b = ngx_create_temp_buf(r->pool, len); @@ -697,7 +703,7 @@ static ngx_buf_t * ngx_http_autoindex_json(ngx_http_request_t *r, ngx_array_t *entries, ngx_str_t *callback) { - size_t len; + size_t len, entry_len; ngx_buf_t *b; ngx_uint_t i; ngx_http_autoindex_entry_t *entry; @@ -714,15 +720,21 @@ ngx_http_autoindex_json(ngx_http_request_t *r, ngx_array_t *entries, entry[i].escape = ngx_escape_json(NULL, entry[i].name.data, entry[i].name.len); - len += sizeof("{ }," CRLF) - 1 - + sizeof("\"name\":\"\"") - 1 - + entry[i].name.len + entry[i].escape - + sizeof(", \"type\":\"directory\"") - 1 - + sizeof(", \"mtime\":\"Wed, 31 Dec 1986 10:00:00 GMT\"") - 1; + entry_len = sizeof("{ }," CRLF) - 1 + + sizeof("\"name\":\"\"") - 1 + + entry[i].name.len + entry[i].escape + + sizeof(", \"type\":\"directory\"") - 1 + + sizeof(", \"mtime\":\"Wed, 31 Dec 1986 10:00:00 GMT\"") - 1; if (entry[i].file) { - len += sizeof(", \"size\":") - 1 + NGX_OFF_T_LEN; + entry_len += sizeof(", \"size\":") - 1 + NGX_OFF_T_LEN; + } + + if (len > NGX_MAX_SIZE_T_VALUE - entry_len) { + return NULL; } + + len += entry_len; } b = ngx_create_temp_buf(r->pool, len); @@ -841,7 +853,7 @@ ngx_http_autoindex_jsonp_callback(ngx_http_request_t *r, ngx_str_t *callback) static ngx_buf_t * ngx_http_autoindex_xml(ngx_http_request_t *r, ngx_array_t *entries) { - size_t len; + size_t len, entry_len; ngx_tm_t tm; ngx_buf_t *b; ngx_str_t type; @@ -859,13 +871,19 @@ ngx_http_autoindex_xml(ngx_http_request_t *r, ngx_array_t *entries) entry[i].escape = ngx_escape_html(NULL, entry[i].name.data, entry[i].name.len); - len += sizeof("<directory></directory>" CRLF) - 1 - + entry[i].name.len + entry[i].escape - + sizeof(" mtime=\"1986-12-31T10:00:00Z\"") - 1; + entry_len = sizeof("<directory></directory>" CRLF) - 1 + + entry[i].name.len + entry[i].escape + + sizeof(" mtime=\"1986-12-31T10:00:00Z\"") - 1; if (entry[i].file) { - len += sizeof(" size=\"\"") - 1 + NGX_OFF_T_LEN; + entry_len += sizeof(" size=\"\"") - 1 + NGX_OFF_T_LEN; + } + + if (len > NGX_MAX_SIZE_T_VALUE - entry_len) { + return NULL; } + + len += entry_len; } b = ngx_create_temp_buf(r->pool, len); |