comparison src/http/modules/ngx_http_autoindex_module.c @ 7435:a91b93f3f3e7

Autoindex: fixed possible integer overflow on 32-bit systems.
author Vladimir Homutov <vl@nginx.com>
date Tue, 25 Dec 2018 12:59:24 +0300
parents 061ec464813f
children
comparison
equal deleted inserted replaced
7434:e3b262e7fc88 7435:a91b93f3f3e7
432 static ngx_buf_t * 432 static ngx_buf_t *
433 ngx_http_autoindex_html(ngx_http_request_t *r, ngx_array_t *entries) 433 ngx_http_autoindex_html(ngx_http_request_t *r, ngx_array_t *entries)
434 { 434 {
435 u_char *last, scale; 435 u_char *last, scale;
436 off_t length; 436 off_t length;
437 size_t len, char_len, escape_html; 437 size_t len, entry_len, char_len, escape_html;
438 ngx_tm_t tm; 438 ngx_tm_t tm;
439 ngx_buf_t *b; 439 ngx_buf_t *b;
440 ngx_int_t size; 440 ngx_int_t size;
441 ngx_uint_t i, utf8; 441 ngx_uint_t i, utf8;
442 ngx_time_t *tp; 442 ngx_time_t *tp;
497 entry[i].name.len); 497 entry[i].name.len);
498 } else { 498 } else {
499 entry[i].utf_len = entry[i].name.len; 499 entry[i].utf_len = entry[i].name.len;
500 } 500 }
501 501
502 len += sizeof("<a href=\"") - 1 502 entry_len = sizeof("<a href=\"") - 1
503 + entry[i].name.len + entry[i].escape 503 + entry[i].name.len + entry[i].escape
504 + 1 /* 1 is for "/" */ 504 + 1 /* 1 is for "/" */
505 + sizeof("\">") - 1 505 + sizeof("\">") - 1
506 + entry[i].name.len - entry[i].utf_len 506 + entry[i].name.len - entry[i].utf_len
507 + entry[i].escape_html 507 + entry[i].escape_html
508 + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof("&gt;") - 2 508 + NGX_HTTP_AUTOINDEX_NAME_LEN + sizeof("&gt;") - 2
509 + sizeof("</a>") - 1 509 + sizeof("</a>") - 1
510 + sizeof(" 28-Sep-1970 12:00 ") - 1 510 + sizeof(" 28-Sep-1970 12:00 ") - 1
511 + 20 /* the file size */ 511 + 20 /* the file size */
512 + 2; 512 + 2;
513
514 if (len > NGX_MAX_SIZE_T_VALUE - entry_len) {
515 return NULL;
516 }
517
518 len += entry_len;
513 } 519 }
514 520
515 b = ngx_create_temp_buf(r->pool, len); 521 b = ngx_create_temp_buf(r->pool, len);
516 if (b == NULL) { 522 if (b == NULL) {
517 return NULL; 523 return NULL;
695 701
696 static ngx_buf_t * 702 static ngx_buf_t *
697 ngx_http_autoindex_json(ngx_http_request_t *r, ngx_array_t *entries, 703 ngx_http_autoindex_json(ngx_http_request_t *r, ngx_array_t *entries,
698 ngx_str_t *callback) 704 ngx_str_t *callback)
699 { 705 {
700 size_t len; 706 size_t len, entry_len;
701 ngx_buf_t *b; 707 ngx_buf_t *b;
702 ngx_uint_t i; 708 ngx_uint_t i;
703 ngx_http_autoindex_entry_t *entry; 709 ngx_http_autoindex_entry_t *entry;
704 710
705 len = sizeof("[" CRLF CRLF "]") - 1; 711 len = sizeof("[" CRLF CRLF "]") - 1;
712 718
713 for (i = 0; i < entries->nelts; i++) { 719 for (i = 0; i < entries->nelts; i++) {
714 entry[i].escape = ngx_escape_json(NULL, entry[i].name.data, 720 entry[i].escape = ngx_escape_json(NULL, entry[i].name.data,
715 entry[i].name.len); 721 entry[i].name.len);
716 722
717 len += sizeof("{ }," CRLF) - 1 723 entry_len = sizeof("{ }," CRLF) - 1
718 + sizeof("\"name\":\"\"") - 1 724 + sizeof("\"name\":\"\"") - 1
719 + entry[i].name.len + entry[i].escape 725 + entry[i].name.len + entry[i].escape
720 + sizeof(", \"type\":\"directory\"") - 1 726 + sizeof(", \"type\":\"directory\"") - 1
721 + sizeof(", \"mtime\":\"Wed, 31 Dec 1986 10:00:00 GMT\"") - 1; 727 + sizeof(", \"mtime\":\"Wed, 31 Dec 1986 10:00:00 GMT\"") - 1;
722 728
723 if (entry[i].file) { 729 if (entry[i].file) {
724 len += sizeof(", \"size\":") - 1 + NGX_OFF_T_LEN; 730 entry_len += sizeof(", \"size\":") - 1 + NGX_OFF_T_LEN;
725 } 731 }
732
733 if (len > NGX_MAX_SIZE_T_VALUE - entry_len) {
734 return NULL;
735 }
736
737 len += entry_len;
726 } 738 }
727 739
728 b = ngx_create_temp_buf(r->pool, len); 740 b = ngx_create_temp_buf(r->pool, len);
729 if (b == NULL) { 741 if (b == NULL) {
730 return NULL; 742 return NULL;
839 851
840 852
841 static ngx_buf_t * 853 static ngx_buf_t *
842 ngx_http_autoindex_xml(ngx_http_request_t *r, ngx_array_t *entries) 854 ngx_http_autoindex_xml(ngx_http_request_t *r, ngx_array_t *entries)
843 { 855 {
844 size_t len; 856 size_t len, entry_len;
845 ngx_tm_t tm; 857 ngx_tm_t tm;
846 ngx_buf_t *b; 858 ngx_buf_t *b;
847 ngx_str_t type; 859 ngx_str_t type;
848 ngx_uint_t i; 860 ngx_uint_t i;
849 ngx_http_autoindex_entry_t *entry; 861 ngx_http_autoindex_entry_t *entry;
857 869
858 for (i = 0; i < entries->nelts; i++) { 870 for (i = 0; i < entries->nelts; i++) {
859 entry[i].escape = ngx_escape_html(NULL, entry[i].name.data, 871 entry[i].escape = ngx_escape_html(NULL, entry[i].name.data,
860 entry[i].name.len); 872 entry[i].name.len);
861 873
862 len += sizeof("<directory></directory>" CRLF) - 1 874 entry_len = sizeof("<directory></directory>" CRLF) - 1
863 + entry[i].name.len + entry[i].escape 875 + entry[i].name.len + entry[i].escape
864 + sizeof(" mtime=\"1986-12-31T10:00:00Z\"") - 1; 876 + sizeof(" mtime=\"1986-12-31T10:00:00Z\"") - 1;
865 877
866 if (entry[i].file) { 878 if (entry[i].file) {
867 len += sizeof(" size=\"\"") - 1 + NGX_OFF_T_LEN; 879 entry_len += sizeof(" size=\"\"") - 1 + NGX_OFF_T_LEN;
868 } 880 }
881
882 if (len > NGX_MAX_SIZE_T_VALUE - entry_len) {
883 return NULL;
884 }
885
886 len += entry_len;
869 } 887 }
870 888
871 b = ngx_create_temp_buf(r->pool, len); 889 b = ngx_create_temp_buf(r->pool, len);
872 if (b == NULL) { 890 if (b == NULL) {
873 return NULL; 891 return NULL;