CVE-2017-20005 (published 2021-06-06T22:15Z)

NGINX before 1.13.6 has a buffer overflow for years that exceed four digits, as demonstrated by a file with a modification date in 1969 that causes an integer overflow (or a false modification date far in the future), when encountered by the autoindex module.

Severity: HIGH
CVSS v2 base score: 7.5 (AV:N/AC:L/Au:N/C:P/I:P/A:P)
CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)

Weakness information:
cwe_id: CWE-190
cwe_name: Integer Overflow or Wraparound
description: The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
extended_description: 
            
            
            
            
         
         

Fix information:
repo_url: https://github.com/nginx/nginx
commit_details: repo_url: https://github.com/nginx/nginx
author: Maxim Dounin
author_date: 2017-09-13 15:53:19+03:00
msg: Introduced time truncation to December 31, 9999 (ticket #1368).

Various buffers are allocated in an assumption that there would be
no more than 4 year digits.  This might not be true on platforms
with 64-bit time_t, as 64-bit time_t is able to represent more than that.
Such dates with more than 4 year digits hardly make sense though, as
various date formats in use do not allow them anyway.

As such, all dates are now truncated by ngx_gmtime() to December 31, 9999.
This should have no effect on valid dates, though will prevent potential
buffer overflows on invalid ones.
repository: repo_url: https://github.com/nginx/nginx
repo_name: nginx/nginx
description: An official read-only mirror of http://hg.nginx.org/nginx/ which is updated hourly. Pull requests on GitHub cannot be accepted and will be automatically closed. The proper way to submit changes to nginx is via the nginx development mailing list, see http://nginx.org/en/docs/contributing_changes.html
repo_language: C
owner: nginx
file_changes: filename: ngx_times.c
change_type: ModificationType.MODIFY
diff: @@ -311,6 +311,16 @@ ngx_gmtime(time_t t, ngx_tm_t *tp)
     days = t / 86400;
     sec = t % 86400;
 
+    /*
+     * no more than 4 year digits supported,
+     * truncate to December 31, 9999, 23:59:59
+     */
+
+    if (days > 2932896) {
+        days = 2932896;
+        sec = 86399;
+    }
+
     /* January 1, 1970 was Thursday */
 
     wday = (4 + days) % 7;

programming_language: C
repo_url: https://github.com/nginx/nginx
commit_details: repo_url: https://github.com/nginx/nginx
author: Maxim Dounin
author_date: 2017-09-13 15:52:01+03:00
msg: Fixed ngx_gmtime() on 32-bit platforms with 64-bit time_t.

In ngx_gmtime(), instead of casting to ngx_uint_t we now work with
time_t directly.  This allows using dates after 2038 on 32-bit platforms
which use 64-bit time_t, notably NetBSD and OpenBSD.

As the code is not able to work with negative time_t values, argument
is now set to 0 for negative values.  As a positive side effect, this
results in Epoch being used for such values instead of a date in distant
future.
repository: repo_url: https://github.com/nginx/nginx
repo_name: nginx/nginx
description: An official read-only mirror of http://hg.nginx.org/nginx/ which is updated hourly. Pull requests on GitHub cannot be accepted and will be automatically closed. The proper way to submit changes to nginx is via the nginx development mailing list, see http://nginx.org/en/docs/contributing_changes.html
repo_language: C
owner: nginx
file_changes: filename: ngx_times.c
change_type: ModificationType.MODIFY
diff: @@ -300,23 +300,25 @@ void
 ngx_gmtime(time_t t, ngx_tm_t *tp)
 {
     ngx_int_t   yday;
-    ngx_uint_t  n, sec, min, hour, mday, mon, year, wday, days, leap;
+    ngx_uint_t  sec, min, hour, mday, mon, year, wday, days, leap;
 
     /* the calculation is valid for positive time_t only */
 
-    n = (ngx_uint_t) t;
+    if (t < 0) {
+        t = 0;
+    }
 
-    days = n / 86400;
+    days = t / 86400;
+    sec = t % 86400;
 
     /* January 1, 1970 was Thursday */
 
     wday = (4 + days) % 7;
 
-    n %= 86400;
-    hour = n / 3600;
-    n %= 3600;
-    min = n / 60;
-    sec = n % 60;
+    hour = sec / 3600;
+    sec %= 3600;
+    min = sec / 60;
+    sec %= 60;
 
     /*
      * the algorithm based on Gauss' formula,

programming_language: C