Mercurial > nginx
changeset 9462:4f55535cf345
Upstream: overflow detection in Cache-Control delta-seconds.
Overflowing calculations are now aligned to the greatest positive integer
as specified in RFC 9111, Section 1.2.2.
| author | Sergey Kandaurov <pluknet@nginx.com> |
|---|---|
| date | Wed, 10 Sep 2025 18:39:52 +0400 |
| parents | c5aa28d71389 |
| children | 0954f084ffc0 |
| files | src/http/ngx_http_upstream.c |
| diffstat | 1 files changed, 50 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/src/http/ngx_http_upstream.c Wed Jul 30 16:26:21 2025 +0400 +++ b/src/http/ngx_http_upstream.c Wed Sep 10 18:39:52 2025 +0400 @@ -116,6 +116,10 @@ static ngx_int_t ngx_http_upstream_process_cache_control(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); +#if (NGX_HTTP_CACHE) +static ngx_int_t ngx_http_upstream_process_delta_seconds(u_char *p, + u_char *last); +#endif static ngx_int_t ngx_http_upstream_ignore_header_line(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset); static ngx_int_t ngx_http_upstream_process_expires(ngx_http_request_t *r, @@ -5066,18 +5070,9 @@ } if (p) { - n = 0; - - for (p += offset; p < last; p++) { - if (*p == ',' || *p == ';' || *p == ' ') { - break; - } - - if (*p >= '0' && *p <= '9') { - n = n * 10 + (*p - '0'); - continue; - } - + n = ngx_http_upstream_process_delta_seconds(p + offset, last); + + if (n == NGX_ERROR) { u->cacheable = 0; return NGX_OK; } @@ -5087,7 +5082,8 @@ return NGX_OK; } - r->cache->valid_sec = ngx_time() + n; + r->cache->valid_sec = ngx_min((ngx_uint_t) ngx_time() + n, + NGX_MAX_INT_T_VALUE); u->headers_in.expired = 0; } @@ -5097,18 +5093,9 @@ 23 - 1); if (p) { - n = 0; - - for (p += 23; p < last; p++) { - if (*p == ',' || *p == ';' || *p == ' ') { - break; - } - - if (*p >= '0' && *p <= '9') { - n = n * 10 + (*p - '0'); - continue; - } - + n = ngx_http_upstream_process_delta_seconds(p + 23, last); + + if (n == NGX_ERROR) { u->cacheable = 0; return NGX_OK; } @@ -5120,18 +5107,9 @@ p = ngx_strlcasestrn(start, last, (u_char *) "stale-if-error=", 15 - 1); if (p) { - n = 0; - - for (p += 15; p < last; p++) { - if (*p == ',' || *p == ';' || *p == ' ') { - break; - } - - if (*p >= '0' && *p <= '9') { - n = n * 10 + (*p - '0'); - continue; - } - + n = ngx_http_upstream_process_delta_seconds(p + 15, last); + + if (n == NGX_ERROR) { u->cacheable = 0; return NGX_OK; } @@ -5145,6 +5123,41 @@ } +#if (NGX_HTTP_CACHE) + +static ngx_int_t +ngx_http_upstream_process_delta_seconds(u_char *p, u_char *last) +{ + ngx_int_t n, cutoff, cutlim; + + cutoff = NGX_MAX_INT_T_VALUE / 10; + cutlim = NGX_MAX_INT_T_VALUE % 10; + + n = 0; + + for ( /* void */ ; p < last; p++) { + if (*p == ',' || *p == ';' || *p == ' ') { + break; + } + + if (*p < '0' || *p > '9') { + return NGX_ERROR; + } + + if (n >= cutoff && (n > cutoff || *p - '0' > cutlim)) { + n = NGX_MAX_INT_T_VALUE; + break; + } + + n = n * 10 + (*p - '0'); + } + + return n; +} + +#endif + + static ngx_int_t ngx_http_upstream_process_expires(ngx_http_request_t *r, ngx_table_elt_t *h, ngx_uint_t offset)
