Compare commits

...

41 Commits

Author SHA1 Message Date
Maxim Dounin f0870afb39 release-1.6.3 tag 2015-04-07 18:57:56 +03:00
Maxim Dounin 9ab16abd02 nginx-1.6.3 changes fix 2015-04-07 18:51:37 +03:00
Maxim Dounin f5db187b07 release-1.6.3 tag 2015-04-07 17:58:54 +03:00
Maxim Dounin 93e86eda88 nginx-1.6.3-RELEASE 2015-04-07 17:58:54 +03:00
Maxim Dounin d9471299c7 Updated OpenSSL used for win32 builds. 2015-03-23 02:44:41 +03:00
Ruslan Ermilov 37115f7595 Overflow detection in ngx_http_parse_chunked(). 2015-03-17 00:26:27 +03:00
Ruslan Ermilov c04312f3eb Overflow detection in ngx_http_range_parse(). 2015-03-17 00:26:24 +03:00
Ruslan Ermilov f335d4e772 Overflow detection in ngx_inet_addr(). 2015-03-17 00:26:22 +03:00
Ruslan Ermilov ad2d8f9939 Core: overflow detection in ngx_parse_time() (ticket #732). 2015-03-17 00:26:20 +03:00
Ruslan Ermilov 3b5ef1b5c9 Refactored ngx_parse_time().
No functional changes.
2015-03-17 00:26:18 +03:00
Ruslan Ermilov bdbb32a743 Core: overflow detection in number parsing functions. 2015-03-17 00:26:15 +03:00
Ruslan Ermilov d0bcef30a2 Core: expose maximum values of time_t and ngx_int_t.
These are needed to detect overflows.
2015-03-17 00:24:34 +03:00
Maxim Dounin 10985599ab Core: fixed potential buffer overrun when initializing hash.
Initial size as calculated from the number of elements may be bigger
than max_size.  If this happens, make sure to set size to max_size.

Reported by Chris West.
2015-02-24 18:37:14 +03:00
Roman Arutyunyan 64ef1891a7 Core: fixed a race resulting in extra sem_post()'s.
The mtx->wait counter was not decremented if we were able to obtain the lock
right after incrementing it.  This resulted in unneeded sem_post() calls,
eventually leading to EOVERFLOW errors being logged, "sem_post() failed
while wake shmtx (75: Value too large for defined data type)".

To close the race, mtx->wait is now decremented if we obtain the lock right
after incrementing it in ngx_shmtx_lock().  The result can become -1 if a
concurrent ngx_shmtx_unlock() decrements mtx->wait before the added code does.
However, that only leads to one extra iteration in the next call of
ngx_shmtx_lock().
2015-02-04 16:22:43 +03:00
Maxim Dounin bf614d7d95 Fixed post_action to not trigger "header already sent" alert.
The alert was introduced in 03ff14058272 (1.5.4), and was triggered on each
post_action invocation.

There is no real need to call header filters in case of post_action,
so return NGX_OK from ngx_http_send_header() if r->post_action is set.
2014-11-28 16:57:50 +03:00
Valentin Bartenev d1d9e40af9 SPDY: push pending data while closing a stream as with keepalive.
This helps to avoid delays in sending the last chunk of data because
of bad interaction between Nagle's algorithm on nginx side and
delayed ACK on the client side.

Delays could also be caused by TCP_CORK/TCP_NOPUSH if SPDY was
working without SSL and sendfile() was used.
2014-11-21 22:51:49 +03:00
Ruslan Ermilov 0f71123120 Resolver: fixed use-after-free memory access.
In 954867a2f0a6, we switched to using resolver node as the
timer event data, so make sure we do not free resolver node
memory until the corresponding timer is deleted.
2014-11-20 15:24:40 +03:00
Maxim Dounin 47a61270d1 SSL: logging level of "inappropriate fallback" (ticket #662).
Patch by Erik Dubbelboer.
2014-11-17 16:38:48 +03:00
Maxim Dounin d7f841489d Fixed possible buffer overrun in "too long header line" logging.
Additionally, ellipsis now always added to make it clear that
the header logged is incomplete.

Reported by Daniil Bondarev.
2014-10-08 17:16:04 +04:00
Yichun Zhang 1b43b3b992 Core: fixed buffer overrun when hash max_size reached. 2014-10-02 12:00:17 -07:00
Maxim Dounin 11929fbce1 Version bump. 2015-04-06 18:54:19 +03:00
Maxim Dounin 40f7f8318f release-1.6.2 tag 2014-09-16 16:23:19 +04:00
Maxim Dounin 93624624cb nginx-1.6.2-RELEASE 2014-09-16 16:23:18 +04:00
Maxim Dounin 87bfd867b6 Updated OpenSSL used for win32 builds. 2014-09-15 18:03:49 +04:00
Maxim Dounin bf23016157 SSL: session id context now includes certificate hash.
This prevents inappropriate session reuse in unrelated server{}
blocks, while preserving ability to restore sessions on other servers
when using TLS Session Tickets.

Additionally, session context is now set even if there is no session cache
configured.  This is needed as it's also used for TLS Session Tickets.

Thanks to Antoine Delignat-Lavaud and Piotr Sikora.
2014-09-15 17:59:47 +04:00
Ruslan Ermilov 2cdbe76ad4 Resolver: notify all waiting requests on timeout.
If a "resolver_timeout" occurs, only the first waiting request
was notified.  Other requests may hang forever.
2014-08-19 15:43:26 +04:00
Ruslan Ermilov 8a875278c8 Resolver: fixed resend on malformed responses.
DNS request resend on malformed responses was broken in 98876ce2a7fd (1.5.8).

Reported by Pramod Korathota.
2014-07-16 10:21:28 +04:00
Maxim Dounin 174f7a8baf Version bump. 2014-09-15 23:39:21 +04:00
Maxim Dounin 167d78addb release-1.6.1 tag 2014-08-05 15:18:34 +04:00
Maxim Dounin d2124bbc7c nginx-1.6.1-RELEASE 2014-08-05 15:18:34 +04:00
Maxim Dounin 3d1275bdbd Mail: discard pipelined commands after SMTP STARTTLS.
The bug had appeared in nginx 1.5.6 (04e43d03e153).

Reported by Chris Boulton.
2014-08-05 12:22:07 +04:00
Maxim Dounin 39bac43204 Reset of r->uri.len on URI parsing errors.
This ensures that debug logging and the $uri variable (if used in
400 Bad Request processing) will not try to access uninitialized
memory.

Found by Sergey Bobrov.
2014-07-18 20:02:11 +04:00
Maxim Dounin e93c65b6f6 Updated PCRE used for win32 builds. 2014-07-04 22:34:03 +04:00
Maxim Dounin c2b718ee9a Updated OpenSSL used for win32 builds. 2014-06-17 11:38:55 +04:00
Maxim Dounin b24b30e74a Mail: added a check for the number of arguments in MAIL/RCPT.
Missed during introduction of the SMTP pipelining support (04e43d03e153,
1.5.6).  Previously, the check wasn't needed as s->buffer was used directly
and the number of arguments didn't matter.

Reported by Svyatoslav Nikolsky.
2014-05-21 21:56:20 +04:00
Maxim Dounin 5afdcc4fc5 Version bump. 2014-08-05 12:20:22 +04:00
Maxim Dounin b21fd25536 release-1.6.0 tag 2014-04-24 16:52:24 +04:00
Maxim Dounin 2c49caea03 nginx-1.6.0-RELEASE 2014-04-24 16:52:24 +04:00
Maxim Konovalov 9e0d7d45e3 Missed comma fixed. A couple of Latin symbols plugged into
Russian text changed to Russian counterparts.
2014-04-23 16:00:59 +00:00
Maxim Dounin b36b64c4fd Version bump. 2014-04-18 20:10:42 +04:00
Maxim Dounin fee2d9c74e stable-1.6 branch 2014-04-18 20:08:47 +04:00
19 changed files with 543 additions and 105 deletions

View File

@ -489,6 +489,7 @@ ngx_param=NGX_OFF_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
ngx_type="time_t"; . auto/types/sizeof
ngx_param=NGX_TIME_T_SIZE; ngx_value=$ngx_size; . auto/types/value
ngx_param=NGX_TIME_T_LEN; ngx_value=$ngx_max_len; . auto/types/value
ngx_param=NGX_MAX_TIME_T_VALUE; ngx_value=$ngx_max_value; . auto/types/value
# syscalls, libc calls and some features

View File

@ -5,6 +5,180 @@
<change_log title="nginx">
<changes ver="1.6.3" date="07.04.2015">
<change type="feature">
<para lang="ru">
теперь директива tcp_nodelay работает для SPDY-соединений.
</para>
<para lang="en">
now the "tcp_nodelay" directive works with SPDY connections.
</para>
</change>
<change type="bugfix">
<para lang="ru">
в обработке ошибок.<br/>
Спасибо Yichun Zhang и Даниилу Бондареву.
</para>
<para lang="en">
in error handling.<br/>
Thanks to Yichun Zhang and Daniil Bondarev.
</para>
</change>
<change type="bugfix">
<para lang="ru">
при использовании директивы post_action
в лог писались сообщения "header already sent";
ошибка появилась в nginx 1.5.4.
</para>
<para lang="en">
alerts "header already sent" appeared in logs
if the "post_action" directive was used;
the bug had appeared in 1.5.4.
</para>
</change>
<change type="bugfix">
<para lang="ru">
в лог могли писаться сообщения "sem_post() failed".
</para>
<para lang="en">
alerts "sem_post() failed" might appear in logs.
</para>
</change>
<change type="bugfix">
<para lang="ru">
в обработке хэш-таблиц.<br/>
Спасибо Chris West.
</para>
<para lang="en">
in hash table handling.<br/>
Thanks to Chris West.
</para>
</change>
<change type="bugfix">
<para lang="ru">
в обработке целочисленных переполнений.<br/>
Спасибо Régis Leroy.
</para>
<para lang="en">
in integer overflow handling.<br/>
Thanks to Régis Leroy.
</para>
</change>
</changes>
<changes ver="1.6.2" date="16.09.2014">
<change type="security">
<para lang="ru">
при использовании общего для нескольких блоков server
разделяемого кэша SSL-сессий или общего ключа для шифрования
TLS session tickets было возможно повторно использовать
SSL-сессию в контексте другого блока server (CVE-2014-3616).<br/>
Спасибо Antoine Delignat-Lavaud.
</para>
<para lang="en">
it was possible to reuse SSL sessions in unrelated contexts
if a shared SSL session cache or the same TLS session ticket key
was used for multiple "server" blocks (CVE-2014-3616).<br/>
Thanks to Antoine Delignat-Lavaud.
</para>
</change>
<change type="bugfix">
<para lang="ru">
запросы могли зависать, если использовался resolver
и DNS-сервер возвращал некорректный ответ;
ошибка появилась в 1.5.8.
</para>
<para lang="en">
requests might hang if resolver was used
and a DNS server returned a malformed response;
the bug had appeared in 1.5.8.
</para>
</change>
<change type="bugfix">
<para lang="ru">
запросы могли зависать, если использовался resolver
и в процессе обращения к DNS-серверу происходил таймаут.
</para>
<para lang="en">
requests might hang if resolver was used
and a timeout occurred during a DNS request.
</para>
</change>
</changes>
<changes ver="1.6.1" date="05.08.2014">
<change type="security">
<para lang="ru">
pipelined-команды не отбрасывались
после команды STARTTLS в SMTP прокси-сервере (CVE-2014-3556);
ошибка появилась в 1.5.6.<br/>
Спасибо Chris Boulton.
</para>
<para lang="en">
pipelined commands were not discarded
after STARTTLS command in SMTP proxy (CVE-2014-3556);
the bug had appeared in 1.5.6.<br/>
Thanks to Chris Boulton.
</para>
</change>
<change type="bugfix">
<para lang="ru">
переменная $uri могла содержать мусор
при возврате ошибок с кодом 400.<br/>
Спасибо Сергею Боброву.
</para>
<para lang="en">
the $uri variable might contain garbage
when returning errors with code 400.<br/>
Thanks to Sergey Bobrov.
</para>
</change>
<change type="bugfix">
<para lang="ru">
в работе параметра none директивы smtp_auth;
ошибка появилась в 1.5.6.<br/>
Спасибо Святославу Никольскому.
</para>
<para lang="en">
in the "none" parameter in the "smtp_auth" directive;
the bug had appeared in 1.5.6.<br/>
Thanks to Svyatoslav Nikolsky.
</para>
</change>
</changes>
<changes ver="1.6.0" date="24.04.2014">
<change>
<para lang="ru">
Стабильная ветка 1.6.x.
</para>
<para lang="en">
1.6.x stable branch.
</para>
</change>
</changes>
<changes ver="1.5.13" date="08.04.2014">
<change type="change">
@ -673,7 +847,7 @@ in error handling in ngx_http_gunzip_filter_module.
<change type="bugfix">
<para lang="ru">
ответы могли зависать
ответы могли зависать,
если использовался модуль ngx_http_spdy_module
и директива auth_request.
</para>
@ -2293,7 +2467,7 @@ the "single" parameter of the "keepalive" directive is now ignored.
<change type="change">
<para lang="ru">
сжатие SSL теперь отключено
в том числе при использовании OpenSSL cтарее 1.0.0.
в том числе при использовании OpenSSL старее 1.0.0.
</para>
<para lang="en">
SSL compression is now disabled when using all versions of OpenSSL,
@ -21030,7 +21204,7 @@ the %3F symbol in the URI was considered as the argument string start.
<change type="feature">
<para lang="ru">
поддержка unix domain сoкетов в модуле ngx_http_proxy_module.
поддержка unix domain сокетов в модуле ngx_http_proxy_module.
</para>
<para lang="en">
the unix domain sockets support in the ngx_http_proxy_module.

View File

@ -5,9 +5,9 @@ NGINX = nginx-$(VER)
TEMP = tmp
OBJS = objs.msvc8
OPENSSL = openssl-1.0.1g
OPENSSL = openssl-1.0.1m
ZLIB = zlib-1.2.8
PCRE = pcre-8.34
PCRE = pcre-8.35
release: export

View File

@ -9,8 +9,8 @@
#define _NGINX_H_INCLUDED_
#define nginx_version 1005014
#define NGINX_VERSION "1.5.14"
#define nginx_version 1006003
#define NGINX_VERSION "1.6.3"
#define NGINX_VER "nginx/" NGINX_VERSION
#define NGINX_VAR "NGINX"

View File

@ -85,8 +85,11 @@ typedef intptr_t ngx_flag_t;
#if (NGX_PTR_SIZE == 4)
#define NGX_INT_T_LEN NGX_INT32_LEN
#define NGX_MAX_INT_T_VALUE 2147483647
#else
#define NGX_INT_T_LEN NGX_INT64_LEN
#define NGX_MAX_INT_T_VALUE 9223372036854775807
#endif

View File

@ -312,6 +312,8 @@ ngx_hash_init(ngx_hash_init_t *hinit, ngx_hash_key_t *names, ngx_uint_t nelts)
continue;
}
size = hinit->max_size;
ngx_log_error(NGX_LOG_WARN, hinit->pool->log, 0,
"could not build optimal %s, you should increase "
"either %s_max_size: %i or %s_bucket_size: %i; "

View File

@ -27,6 +27,10 @@ ngx_inet_addr(u_char *text, size_t len)
for (p = text; p < text + len; p++) {
if (octet > 255) {
return INADDR_NONE;
}
c = *p;
if (c >= '0' && c <= '9') {
@ -34,7 +38,7 @@ ngx_inet_addr(u_char *text, size_t len)
continue;
}
if (c == '.' && octet < 256) {
if (c == '.') {
addr = (addr << 8) + octet;
octet = 0;
n++;
@ -44,7 +48,7 @@ ngx_inet_addr(u_char *text, size_t len)
return INADDR_NONE;
}
if (n == 3 && octet < 256) {
if (n == 3) {
addr = (addr << 8) + octet;
return htonl(addr);
}

View File

@ -12,10 +12,9 @@
ssize_t
ngx_parse_size(ngx_str_t *line)
{
u_char unit;
size_t len;
ssize_t size;
ngx_int_t scale;
u_char unit;
size_t len;
ssize_t size, scale, max;
len = line->len;
unit = line->data[len - 1];
@ -24,21 +23,24 @@ ngx_parse_size(ngx_str_t *line)
case 'K':
case 'k':
len--;
max = NGX_MAX_SIZE_T_VALUE / 1024;
scale = 1024;
break;
case 'M':
case 'm':
len--;
max = NGX_MAX_SIZE_T_VALUE / (1024 * 1024);
scale = 1024 * 1024;
break;
default:
max = NGX_MAX_SIZE_T_VALUE;
scale = 1;
}
size = ngx_atosz(line->data, len);
if (size == NGX_ERROR) {
if (size == NGX_ERROR || size > max) {
return NGX_ERROR;
}
@ -51,10 +53,9 @@ ngx_parse_size(ngx_str_t *line)
off_t
ngx_parse_offset(ngx_str_t *line)
{
u_char unit;
off_t offset;
size_t len;
ngx_int_t scale;
u_char unit;
off_t offset, scale, max;
size_t len;
len = line->len;
unit = line->data[len - 1];
@ -63,27 +64,31 @@ ngx_parse_offset(ngx_str_t *line)
case 'K':
case 'k':
len--;
max = NGX_MAX_OFF_T_VALUE / 1024;
scale = 1024;
break;
case 'M':
case 'm':
len--;
max = NGX_MAX_OFF_T_VALUE / (1024 * 1024);
scale = 1024 * 1024;
break;
case 'G':
case 'g':
len--;
max = NGX_MAX_OFF_T_VALUE / (1024 * 1024 * 1024);
scale = 1024 * 1024 * 1024;
break;
default:
max = NGX_MAX_OFF_T_VALUE;
scale = 1;
}
offset = ngx_atoof(line->data, len);
if (offset == NGX_ERROR) {
if (offset == NGX_ERROR || offset > max) {
return NGX_ERROR;
}
@ -98,7 +103,8 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
{
u_char *p, *last;
ngx_int_t value, total, scale;
ngx_uint_t max, valid;
ngx_int_t max, cutoff, cutlim;
ngx_uint_t valid;
enum {
st_start = 0,
st_year,
@ -115,8 +121,9 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
valid = 0;
value = 0;
total = 0;
cutoff = NGX_MAX_INT_T_VALUE / 10;
cutlim = NGX_MAX_INT_T_VALUE % 10;
step = is_sec ? st_start : st_month;
scale = is_sec ? 1 : 1000;
p = line->data;
last = p + line->len;
@ -124,6 +131,10 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
while (p < last) {
if (*p >= '0' && *p <= '9') {
if (value >= cutoff && (value > cutoff || *p - '0' > cutlim)) {
return NGX_ERROR;
}
value = value * 10 + (*p++ - '0');
valid = 1;
continue;
@ -136,7 +147,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
return NGX_ERROR;
}
step = st_year;
max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 365);
max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 365);
scale = 60 * 60 * 24 * 365;
break;
@ -145,7 +156,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
return NGX_ERROR;
}
step = st_month;
max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 30);
max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 30);
scale = 60 * 60 * 24 * 30;
break;
@ -154,7 +165,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
return NGX_ERROR;
}
step = st_week;
max = NGX_MAX_INT32_VALUE / (60 * 60 * 24 * 7);
max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24 * 7);
scale = 60 * 60 * 24 * 7;
break;
@ -163,7 +174,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
return NGX_ERROR;
}
step = st_day;
max = NGX_MAX_INT32_VALUE / (60 * 60 * 24);
max = NGX_MAX_INT_T_VALUE / (60 * 60 * 24);
scale = 60 * 60 * 24;
break;
@ -172,7 +183,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
return NGX_ERROR;
}
step = st_hour;
max = NGX_MAX_INT32_VALUE / (60 * 60);
max = NGX_MAX_INT_T_VALUE / (60 * 60);
scale = 60 * 60;
break;
@ -183,7 +194,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
}
p++;
step = st_msec;
max = NGX_MAX_INT32_VALUE;
max = NGX_MAX_INT_T_VALUE;
scale = 1;
break;
}
@ -192,7 +203,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
return NGX_ERROR;
}
step = st_min;
max = NGX_MAX_INT32_VALUE / 60;
max = NGX_MAX_INT_T_VALUE / 60;
scale = 60;
break;
@ -201,7 +212,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
return NGX_ERROR;
}
step = st_sec;
max = NGX_MAX_INT32_VALUE;
max = NGX_MAX_INT_T_VALUE;
scale = 1;
break;
@ -210,7 +221,7 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
return NGX_ERROR;
}
step = st_last;
max = NGX_MAX_INT32_VALUE;
max = NGX_MAX_INT_T_VALUE;
scale = 1;
break;
@ -223,27 +234,40 @@ ngx_parse_time(ngx_str_t *line, ngx_uint_t is_sec)
max /= 1000;
}
if ((ngx_uint_t) value > max) {
if (value > max) {
return NGX_ERROR;
}
total += value * scale;
value *= scale;
if ((ngx_uint_t) total > NGX_MAX_INT32_VALUE) {
if (total > NGX_MAX_INT_T_VALUE - value) {
return NGX_ERROR;
}
total += value;
value = 0;
scale = is_sec ? 1 : 1000;
while (p < last && *p == ' ') {
p++;
}
}
if (valid) {
return total + value * scale;
if (!valid) {
return NGX_ERROR;
}
return NGX_ERROR;
if (!is_sec) {
if (value > NGX_MAX_INT_T_VALUE / 1000) {
return NGX_ERROR;
}
value *= 1000;
}
if (total > NGX_MAX_INT_T_VALUE - value) {
return NGX_ERROR;
}
return total + value;
}

View File

@ -417,7 +417,7 @@ ngx_resolve_name_done(ngx_resolver_ctx_t *ctx)
/* lock name mutex */
if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
if (ctx->state == NGX_AGAIN) {
hash = ngx_crc32_short(ctx->name.data, ctx->name.len);
@ -664,7 +664,7 @@ ngx_resolve_name_locked(ngx_resolver_t *r, ngx_resolver_ctx_t *ctx)
}
ctx->event->handler = ngx_resolver_timeout_handler;
ctx->event->data = ctx;
ctx->event->data = rn;
ctx->event->log = r->log;
ctx->ident = -1;
@ -857,7 +857,7 @@ ngx_resolve_addr(ngx_resolver_ctx_t *ctx)
}
ctx->event->handler = ngx_resolver_timeout_handler;
ctx->event->data = ctx;
ctx->event->data = rn;
ctx->event->log = r->log;
ctx->ident = -1;
@ -949,7 +949,7 @@ ngx_resolve_addr_done(ngx_resolver_ctx_t *ctx)
/* lock addr mutex */
if (ctx->state == NGX_AGAIN || ctx->state == NGX_RESOLVE_TIMEDOUT) {
if (ctx->state == NGX_AGAIN) {
switch (ctx->addr.sockaddr->sa_family) {
@ -1467,7 +1467,6 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
goto failed;
}
rn->naddrs6 = 0;
qident = (rn->query6[0] << 8) + rn->query6[1];
break;
@ -1482,7 +1481,6 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
goto failed;
}
rn->naddrs = 0;
qident = (rn->query[0] << 8) + rn->query[1];
}
@ -1507,6 +1505,8 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
case NGX_RESOLVE_AAAA:
rn->naddrs6 = 0;
if (rn->naddrs == (u_short) -1) {
goto next;
}
@ -1519,6 +1519,8 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
default: /* NGX_RESOLVE_A */
rn->naddrs = 0;
if (rn->naddrs6 == (u_short) -1) {
goto next;
}
@ -1539,6 +1541,8 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
case NGX_RESOLVE_AAAA:
rn->naddrs6 = 0;
if (rn->naddrs == (u_short) -1) {
rn->code = (u_char) code;
goto next;
@ -1548,6 +1552,8 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
default: /* NGX_RESOLVE_A */
rn->naddrs = 0;
if (rn->naddrs6 == (u_short) -1) {
rn->code = (u_char) code;
goto next;
@ -1562,8 +1568,6 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
ngx_rbtree_delete(&r->name_rbtree, &rn->node);
ngx_resolver_free_node(r, rn);
/* unlock name mutex */
while (next) {
@ -1574,6 +1578,8 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
ctx->handler(ctx);
}
ngx_resolver_free_node(r, rn);
return;
}
@ -1817,6 +1823,25 @@ ngx_resolver_process_a(ngx_resolver_t *r, u_char *buf, size_t last,
}
}
switch (qtype) {
#if (NGX_HAVE_INET6)
case NGX_RESOLVE_AAAA:
if (rn->naddrs6 == (u_short) -1) {
rn->naddrs6 = 0;
}
break;
#endif
default: /* NGX_RESOLVE_A */
if (rn->naddrs == (u_short) -1) {
rn->naddrs = 0;
}
}
if (rn->naddrs != (u_short) -1
#if (NGX_HAVE_INET6)
&& rn->naddrs6 != (u_short) -1
@ -2118,8 +2143,6 @@ valid:
ngx_rbtree_delete(tree, &rn->node);
ngx_resolver_free_node(r, rn);
/* unlock addr mutex */
while (next) {
@ -2130,6 +2153,8 @@ valid:
ctx->handler(ctx);
}
ngx_resolver_free_node(r, rn);
return;
}
@ -2766,13 +2791,21 @@ done:
static void
ngx_resolver_timeout_handler(ngx_event_t *ev)
{
ngx_resolver_ctx_t *ctx;
ngx_resolver_ctx_t *ctx, *next;
ngx_resolver_node_t *rn;
ctx = ev->data;
rn = ev->data;
ctx = rn->waiting;
rn->waiting = NULL;
ctx->state = NGX_RESOLVE_TIMEDOUT;
do {
ctx->state = NGX_RESOLVE_TIMEDOUT;
next = ctx->next;
ctx->handler(ctx);
ctx->handler(ctx);
ctx = next;
} while (ctx);
}

View File

@ -101,6 +101,7 @@ ngx_shmtx_lock(ngx_shmtx_t *mtx)
(void) ngx_atomic_fetch_add(mtx->wait, 1);
if (*mtx->lock == 0 && ngx_atomic_cmp_set(mtx->lock, 0, ngx_pid)) {
(void) ngx_atomic_fetch_add(mtx->wait, -1);
return;
}
@ -174,7 +175,7 @@ ngx_shmtx_wakeup(ngx_shmtx_t *mtx)
wait = *mtx->wait;
if (wait == 0) {
if ((ngx_atomic_int_t) wait <= 0) {
return;
}

View File

@ -897,26 +897,28 @@ ngx_filename_cmp(u_char *s1, u_char *s2, size_t n)
ngx_int_t
ngx_atoi(u_char *line, size_t n)
{
ngx_int_t value;
ngx_int_t value, cutoff, cutlim;
if (n == 0) {
return NGX_ERROR;
}
cutoff = NGX_MAX_INT_T_VALUE / 10;
cutlim = NGX_MAX_INT_T_VALUE % 10;
for (value = 0; n--; line++) {
if (*line < '0' || *line > '9') {
return NGX_ERROR;
}
if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) {
return NGX_ERROR;
}
value = value * 10 + (*line - '0');
}
if (value < 0) {
return NGX_ERROR;
} else {
return value;
}
return value;
}
@ -925,13 +927,16 @@ ngx_atoi(u_char *line, size_t n)
ngx_int_t
ngx_atofp(u_char *line, size_t n, size_t point)
{
ngx_int_t value;
ngx_int_t value, cutoff, cutlim;
ngx_uint_t dot;
if (n == 0) {
return NGX_ERROR;
}
cutoff = NGX_MAX_INT_T_VALUE / 10;
cutlim = NGX_MAX_INT_T_VALUE % 10;
dot = 0;
for (value = 0; n--; line++) {
@ -953,98 +958,107 @@ ngx_atofp(u_char *line, size_t n, size_t point)
return NGX_ERROR;
}
if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) {
return NGX_ERROR;
}
value = value * 10 + (*line - '0');
point -= dot;
}
while (point--) {
if (value > cutoff) {
return NGX_ERROR;
}
value = value * 10;
}
if (value < 0) {
return NGX_ERROR;
} else {
return value;
}
return value;
}
ssize_t
ngx_atosz(u_char *line, size_t n)
{
ssize_t value;
ssize_t value, cutoff, cutlim;
if (n == 0) {
return NGX_ERROR;
}
cutoff = NGX_MAX_SIZE_T_VALUE / 10;
cutlim = NGX_MAX_SIZE_T_VALUE % 10;
for (value = 0; n--; line++) {
if (*line < '0' || *line > '9') {
return NGX_ERROR;
}
if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) {
return NGX_ERROR;
}
value = value * 10 + (*line - '0');
}
if (value < 0) {
return NGX_ERROR;
} else {
return value;
}
return value;
}
off_t
ngx_atoof(u_char *line, size_t n)
{
off_t value;
off_t value, cutoff, cutlim;
if (n == 0) {
return NGX_ERROR;
}
cutoff = NGX_MAX_OFF_T_VALUE / 10;
cutlim = NGX_MAX_OFF_T_VALUE % 10;
for (value = 0; n--; line++) {
if (*line < '0' || *line > '9') {
return NGX_ERROR;
}
if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) {
return NGX_ERROR;
}
value = value * 10 + (*line - '0');
}
if (value < 0) {
return NGX_ERROR;
} else {
return value;
}
return value;
}
time_t
ngx_atotm(u_char *line, size_t n)
{
time_t value;
time_t value, cutoff, cutlim;
if (n == 0) {
return NGX_ERROR;
}
cutoff = NGX_MAX_TIME_T_VALUE / 10;
cutlim = NGX_MAX_TIME_T_VALUE % 10;
for (value = 0; n--; line++) {
if (*line < '0' || *line > '9') {
return NGX_ERROR;
}
if (value >= cutoff && (value > cutoff || *line - '0' > cutlim)) {
return NGX_ERROR;
}
value = value * 10 + (*line - '0');
}
if (value < 0) {
return NGX_ERROR;
} else {
return value;
}
return value;
}
@ -1052,13 +1066,19 @@ ngx_int_t
ngx_hextoi(u_char *line, size_t n)
{
u_char c, ch;
ngx_int_t value;
ngx_int_t value, cutoff;
if (n == 0) {
return NGX_ERROR;
}
cutoff = NGX_MAX_INT_T_VALUE / 16;
for (value = 0; n--; line++) {
if (value > cutoff) {
return NGX_ERROR;
}
ch = *line;
if (ch >= '0' && ch <= '9') {
@ -1076,12 +1096,7 @@ ngx_hextoi(u_char *line, size_t n)
return NGX_ERROR;
}
if (value < 0) {
return NGX_ERROR;
} else {
return value;
}
return value;
}

View File

@ -27,6 +27,8 @@ static void ngx_ssl_connection_error(ngx_connection_t *c, int sslerr,
ngx_err_t err, char *text);
static void ngx_ssl_clear_error(ngx_log_t *log);
static ngx_int_t ngx_ssl_session_id_context(ngx_ssl_t *ssl,
ngx_str_t *sess_ctx);
ngx_int_t ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data);
static int ngx_ssl_new_session(ngx_ssl_conn_t *ssl_conn,
ngx_ssl_session_t *sess);
@ -1611,6 +1613,9 @@ ngx_ssl_connection_error(ngx_connection_t *c, int sslerr, ngx_err_t err,
#endif
#ifdef SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING
|| n == SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING /* 345 */
#endif
#ifdef SSL_R_INAPPROPRIATE_FALLBACK
|| n == SSL_R_INAPPROPRIATE_FALLBACK /* 373 */
#endif
|| n == 1000 /* SSL_R_SSLV3_ALERT_CLOSE_NOTIFY */
|| n == SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE /* 1010 */
@ -1729,13 +1734,15 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
SSL_CTX_set_timeout(ssl->ctx, (long) timeout);
if (ngx_ssl_session_id_context(ssl, sess_ctx) != NGX_OK) {
return NGX_ERROR;
}
if (builtin_session_cache == NGX_SSL_NO_SCACHE) {
SSL_CTX_set_session_cache_mode(ssl->ctx, SSL_SESS_CACHE_OFF);
return NGX_OK;
}
SSL_CTX_set_session_id_context(ssl->ctx, sess_ctx->data, sess_ctx->len);
if (builtin_session_cache == NGX_SSL_NONE_SCACHE) {
/*
@ -1792,6 +1799,96 @@ ngx_ssl_session_cache(ngx_ssl_t *ssl, ngx_str_t *sess_ctx,
}
static ngx_int_t
ngx_ssl_session_id_context(ngx_ssl_t *ssl, ngx_str_t *sess_ctx)
{
int n, i;
X509 *cert;
X509_NAME *name;
EVP_MD_CTX md;
unsigned int len;
STACK_OF(X509_NAME) *list;
u_char buf[EVP_MAX_MD_SIZE];
/*
* Session ID context is set based on the string provided,
* the server certificate, and the client CA list.
*/
EVP_MD_CTX_init(&md);
if (EVP_DigestInit_ex(&md, EVP_sha1(), NULL) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"EVP_DigestInit_ex() failed");
goto failed;
}
if (EVP_DigestUpdate(&md, sess_ctx->data, sess_ctx->len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"EVP_DigestUpdate() failed");
goto failed;
}
cert = SSL_CTX_get_ex_data(ssl->ctx, ngx_ssl_certificate_index);
if (X509_digest(cert, EVP_sha1(), buf, &len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"X509_digest() failed");
goto failed;
}
if (EVP_DigestUpdate(&md, buf, len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"EVP_DigestUpdate() failed");
goto failed;
}
list = SSL_CTX_get_client_CA_list(ssl->ctx);
if (list != NULL) {
n = sk_X509_NAME_num(list);
for (i = 0; i < n; i++) {
name = sk_X509_NAME_value(list, i);
if (X509_NAME_digest(name, EVP_sha1(), buf, &len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"X509_NAME_digest() failed");
goto failed;
}
if (EVP_DigestUpdate(&md, buf, len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"EVP_DigestUpdate() failed");
goto failed;
}
}
}
if (EVP_DigestFinal_ex(&md, buf, &len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"EVP_DigestUpdate() failed");
goto failed;
}
EVP_MD_CTX_cleanup(&md);
if (SSL_CTX_set_session_id_context(ssl->ctx, buf, len) == 0) {
ngx_ssl_error(NGX_LOG_EMERG, ssl->log, 0,
"SSL_CTX_set_session_id_context() failed");
return NGX_ERROR;
}
return NGX_OK;
failed:
EVP_MD_CTX_cleanup(&md);
return NGX_ERROR;
}
ngx_int_t
ngx_ssl_session_cache_init(ngx_shm_zone_t *shm_zone, void *data)
{

View File

@ -274,7 +274,7 @@ ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx,
ngx_uint_t ranges)
{
u_char *p;
off_t start, end, size, content_length;
off_t start, end, size, content_length, cutoff, cutlim;
ngx_uint_t suffix;
ngx_http_range_t *range;
@ -282,6 +282,9 @@ ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx,
size = 0;
content_length = r->headers_out.content_length_n;
cutoff = NGX_MAX_OFF_T_VALUE / 10;
cutlim = NGX_MAX_OFF_T_VALUE % 10;
for ( ;; ) {
start = 0;
end = 0;
@ -295,6 +298,10 @@ ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx,
}
while (*p >= '0' && *p <= '9') {
if (start >= cutoff && (start > cutoff || *p - '0' > cutlim)) {
return NGX_HTTP_RANGE_NOT_SATISFIABLE;
}
start = start * 10 + *p++ - '0';
}
@ -321,6 +328,10 @@ ngx_http_range_parse(ngx_http_request_t *r, ngx_http_range_filter_ctx_t *ctx,
}
while (*p >= '0' && *p <= '9') {
if (end >= cutoff && (end > cutoff || *p - '0' > cutlim)) {
return NGX_HTTP_RANGE_NOT_SATISFIABLE;
}
end = end * 10 + *p++ - '0';
}

View File

@ -1935,6 +1935,10 @@ ngx_http_send_response(ngx_http_request_t *r, ngx_uint_t status,
ngx_int_t
ngx_http_send_header(ngx_http_request_t *r)
{
if (r->post_action) {
return NGX_OK;
}
if (r->header_sent) {
ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
"header already sent");

View File

@ -2104,6 +2104,10 @@ ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b,
goto invalid;
case sw_chunk_size:
if (ctx->size > NGX_MAX_OFF_T_VALUE / 16) {
goto invalid;
}
if (ch >= '0' && ch <= '9') {
ctx->size = ctx->size * 16 + (ch - '0');
break;
@ -2253,6 +2257,10 @@ data:
ctx->state = state;
b->pos = pos;
if (ctx->size > NGX_MAX_OFF_T_VALUE - 5) {
goto invalid;
}
switch (state) {
case sw_chunk_start:
@ -2289,10 +2297,6 @@ data:
}
if (ctx->size < 0 || ctx->length < 0) {
goto invalid;
}
return rc;
done:

View File

@ -1071,6 +1071,8 @@ ngx_http_process_request_uri(ngx_http_request_t *r)
cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
if (ngx_http_parse_complex_uri(r, cscf->merge_slashes) != NGX_OK) {
r->uri.len = 0;
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"client sent invalid request");
ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
@ -1225,12 +1227,11 @@ ngx_http_process_request_headers(ngx_event_t *rev)
if (len > NGX_MAX_ERROR_STR - 300) {
len = NGX_MAX_ERROR_STR - 300;
p[len++] = '.'; p[len++] = '.'; p[len++] = '.';
}
ngx_log_error(NGX_LOG_INFO, c->log, 0,
"client sent too long header line: \"%*s\"",
len, r->header_name_start);
"client sent too long header line: \"%*s...\"",
len, r->header_name_start);
ngx_http_finalize_request(r,
NGX_HTTP_REQUEST_HEADER_TOO_LARGE);

View File

@ -3156,8 +3156,10 @@ ngx_http_spdy_close_stream_handler(ngx_event_t *ev)
void
ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
{
int tcp_nodelay;
ngx_event_t *ev;
ngx_connection_t *fc;
ngx_connection_t *c, *fc;
ngx_http_core_loc_conf_t *clcf;
ngx_http_spdy_stream_t **index, *s;
ngx_http_spdy_srv_conf_t *sscf;
ngx_http_spdy_connection_t *sc;
@ -3183,6 +3185,54 @@ ngx_http_spdy_close_stream(ngx_http_spdy_stream_t *stream, ngx_int_t rc)
{
sc->connection->error = 1;
}
} else {
c = sc->connection;
if (c->tcp_nopush == NGX_TCP_NOPUSH_SET) {
if (ngx_tcp_push(c->fd) == -1) {
ngx_connection_error(c, ngx_socket_errno,
ngx_tcp_push_n " failed");
c->error = 1;
tcp_nodelay = 0;
} else {
c->tcp_nopush = NGX_TCP_NOPUSH_UNSET;
tcp_nodelay = ngx_tcp_nodelay_and_tcp_nopush ? 1 : 0;
}
} else {
tcp_nodelay = 1;
}
clcf = ngx_http_get_module_loc_conf(stream->request,
ngx_http_core_module);
if (tcp_nodelay
&& clcf->tcp_nodelay
&& c->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
{
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0, "tcp_nodelay");
if (setsockopt(c->fd, IPPROTO_TCP, TCP_NODELAY,
(const void *) &tcp_nodelay, sizeof(int))
== -1)
{
#if (NGX_SOLARIS)
/* Solaris returns EINVAL if a socket has been shut down */
c->log_error = NGX_ERROR_IGNORE_EINVAL;
#endif
ngx_connection_error(c, ngx_socket_errno,
"setsockopt(TCP_NODELAY) failed");
c->log_error = NGX_ERROR_INFO;
c->error = 1;
} else {
c->tcp_nodelay = NGX_TCP_NODELAY_SET;
}
}
}
if (sc->stream == stream) {

View File

@ -679,6 +679,11 @@ ngx_mail_smtp_mail(ngx_mail_session_t *s, ngx_connection_t *c)
return NGX_OK;
}
if (s->args.nelts == 0) {
ngx_str_set(&s->out, smtp_invalid_argument);
return NGX_OK;
}
arg = s->args.elts;
arg += s->args.nelts - 1;
@ -713,6 +718,11 @@ ngx_mail_smtp_rcpt(ngx_mail_session_t *s, ngx_connection_t *c)
return NGX_OK;
}
if (s->args.nelts == 0) {
ngx_str_set(&s->out, smtp_invalid_argument);
return NGX_OK;
}
arg = s->args.elts;
arg += s->args.nelts - 1;
@ -767,6 +777,9 @@ ngx_mail_smtp_starttls(ngx_mail_session_t *s, ngx_connection_t *c)
ngx_str_null(&s->smtp_from);
ngx_str_null(&s->smtp_to);
s->buffer->pos = s->buffer->start;
s->buffer->last = s->buffer->start;
c->read->handler = ngx_mail_starttls_handler;
return NGX_OK;
}

View File

@ -175,6 +175,7 @@ typedef int sig_atomic_t;
#define NGX_MAX_SIZE_T_VALUE 2147483647
#define NGX_TIME_T_LEN (sizeof("-2147483648") - 1)
#define NGX_TIME_T_SIZE 4
#define NGX_MAX_TIME_T_VALUE 2147483647
#define NGX_OFF_T_LEN (sizeof("-9223372036854775807") - 1)
#define NGX_MAX_OFF_T_VALUE 9223372036854775807
#define NGX_SIG_ATOMIC_T_SIZE 4