Merge branch 'nginx' (nginx-1.17.4).
Change-Id: Ieb1e8b9a7e6d883c7a15fbe2868093a07691f17a
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
diff --git a/.hgtags b/.hgtags
index ec85611..19ec901 100644
--- a/.hgtags
+++ b/.hgtags
@@ -442,3 +442,4 @@
7816bd7dabf6ee86c53c073b90a7143161546e06 release-1.17.1
2fc9f853a6b7cd29dc84e0af2ed3cf78e0da6ca8 release-1.17.2
ed4303aa1b31a9aad5440640c0840d9d0af45fed release-1.17.3
+ce2ced3856909f36f8130c99eaa4dbdbae636ddc release-1.17.4
diff --git a/BUILD b/BUILD
index 10b0b42..bfe49ee 100644
--- a/BUILD
+++ b/BUILD
@@ -1520,5 +1520,5 @@
preinst = "@nginx_pkgoss//:debian_preinst",
prerm = "@nginx_pkgoss//:debian_prerm",
section = "httpd",
- version = "1.17.3",
+ version = "1.17.4",
)
diff --git a/build.bzl b/build.bzl
index 76b5029..662cfa4 100644
--- a/build.bzl
+++ b/build.bzl
@@ -673,9 +673,9 @@
name = "nginx_pkgoss",
build_file_content = _PKGOSS_BUILD_FILE.format(nginx = nginx) +
_PKGOSS_BUILD_FILE_TAIL,
- commit = "f1d1a9fbc78c37a28de92df4e4cbed9268aa7304", # nginx-1.17.3
+ commit = "b111e7858767a7f112093e752eba1a27a69bf778", # nginx-1.17.4
remote = "https://nginx.googlesource.com/nginx-pkgoss",
- shallow_since = "1565719153 +0300",
+ shallow_since = "1569336583 +0300",
)
def nginx_repositories_zlib(bind):
diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml
index 492b469..fd7e308 100644
--- a/docs/xml/nginx/changes.xml
+++ b/docs/xml/nginx/changes.xml
@@ -5,6 +5,95 @@
<change_log title="nginx">
+<changes ver="1.17.4" date="2019-09-24">
+
+<change type="change">
+<para lang="ru">
+улучшено детектирование некорректного поведения клиентов в HTTP/2.
+</para>
+<para lang="en">
+better detection of incorrect client behavior in HTTP/2.
+</para>
+</change>
+
+<change type="change">
+<para lang="ru">
+в обработке непрочитанного тела запроса
+при возврате ошибок в HTTP/2.
+</para>
+<para lang="en">
+in handling of not fully read client request body
+when returning errors in HTTP/2.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+директива worker_shutdown_timeout могла не работать
+при использовании HTTP/2.
+</para>
+<para lang="en">
+the "worker_shutdown_timeout" directive might not work
+when using HTTP/2.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+при использовании HTTP/2 и директивы proxy_request_buffering
+в рабочем процессе мог произойти segmentation fault.
+</para>
+<para lang="en">
+a segmentation fault might occur in a worker process
+when using HTTP/2 and the "proxy_request_buffering" directive.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+на Windows при использовании SSL
+уровень записи в лог ошибки ECONNABORTED был "crit" вместо "error".
+</para>
+<para lang="en">
+the ECONNABORTED error log level was "crit" instead of "error"
+on Windows when using SSL.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+nginx игнорировал лишние данные при использовании chunked transfer encoding.
+</para>
+<para lang="en">
+nginx ignored extra data when using chunked transfer encoding.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+если использовалась директива return и
+при чтении тела запроса возникала ошибка,
+nginx всегда возвращал ошибку 500.
+</para>
+<para lang="en">
+nginx always returned the 500 error
+if the "return" directive was used
+and an error occurred during reading client request body.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+в обработке ошибок выделения памяти.
+</para>
+<para lang="en">
+in memory allocation error handling.
+</para>
+</change>
+
+</changes>
+
+
<changes ver="1.17.3" date="2019-08-13">
<change type="security">
diff --git a/misc/GNUmakefile b/misc/GNUmakefile
index 2a34ae5..6938fe9 100644
--- a/misc/GNUmakefile
+++ b/misc/GNUmakefile
@@ -6,7 +6,7 @@
CC = cl
OBJS = objs.msvc8
-OPENSSL = openssl-1.1.1c
+OPENSSL = openssl-1.1.1d
ZLIB = zlib-1.2.11
PCRE = pcre-8.43
diff --git a/src/core/nginx.h b/src/core/nginx.h
index 3b0b837..053201d 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -13,8 +13,8 @@
#define NGINX_NAME "nginx"
#endif
-#define nginx_version 1017003
-#define NGINX_VERSION "1.17.3"
+#define nginx_version 1017004
+#define NGINX_VERSION "1.17.4"
#define NGINX_VER NGINX_NAME "/" NGINX_VERSION
#ifdef NGX_BUILD
diff --git a/src/core/ngx_resolver.c b/src/core/ngx_resolver.c
index 593645d..e51712c 100644
--- a/src/core/ngx_resolver.c
+++ b/src/core/ngx_resolver.c
@@ -972,7 +972,8 @@
name = ngx_resolver_dup(r, rn->name, rn->nlen);
if (name == NULL) {
- goto failed;
+ ngx_resolver_free(r, ctx);
+ return NGX_ERROR;
}
ctx->name.len = rn->nlen;
diff --git a/src/event/ngx_event_openssl.c b/src/event/ngx_event_openssl.c
index 5abd167..b8d7b08 100644
--- a/src/event/ngx_event_openssl.c
+++ b/src/event/ngx_event_openssl.c
@@ -2837,6 +2837,9 @@
if (sslerr == SSL_ERROR_SYSCALL) {
if (err == NGX_ECONNRESET
+#if (NGX_WIN32)
+ || err == NGX_ECONNABORTED
+#endif
|| err == NGX_EPIPE
|| err == NGX_ENOTCONN
|| err == NGX_ETIMEDOUT
diff --git a/src/http/modules/ngx_http_ssl_module.c b/src/http/modules/ngx_http_ssl_module.c
index 9adce1b..74741f5 100644
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -790,7 +790,7 @@
if (conf->client_certificate.len == 0 && conf->verify != 3) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no ssl_client_certificate for ssl_client_verify");
+ "no ssl_client_certificate for ssl_verify_client");
return NGX_CONF_ERROR;
}
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 110cb8a..1afdb19 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1660,8 +1660,10 @@
ngx_buf_t *b;
ngx_chain_t out;
- if (ngx_http_discard_request_body(r) != NGX_OK) {
- return NGX_HTTP_INTERNAL_SERVER_ERROR;
+ rc = ngx_http_discard_request_body(r);
+
+ if (rc != NGX_OK) {
+ return rc;
}
r->headers_out.status = status;
diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c
index d9a1dbe..8e1b118 100644
--- a/src/http/ngx_http_parse.c
+++ b/src/http/ngx_http_parse.c
@@ -2268,6 +2268,9 @@
break;
case LF:
state = sw_chunk_start;
+ break;
+ default:
+ goto invalid;
}
break;
diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c
index 8d0d54f..345d1fc 100644
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -355,6 +355,11 @@
if (c->close) {
c->close = 0;
+ if (c->error) {
+ ngx_http_v2_finalize_connection(h2c, 0);
+ return;
+ }
+
if (!h2c->goaway) {
h2c->goaway = 1;
@@ -420,6 +425,14 @@
} while (p != end);
+ h2c->total_bytes += n;
+
+ if (h2c->total_bytes / 8 > h2c->payload_bytes + 1048576) {
+ ngx_log_error(NGX_LOG_INFO, c->log, 0, "http2 flood detected");
+ ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
+ return;
+ }
+
} while (rev->ready);
if (ngx_handle_read_event(rev, 0) != NGX_OK) {
@@ -506,13 +519,12 @@
ngx_http_core_loc_conf_t *clcf;
c = h2c->connection;
+ wev = c->write;
if (c->error) {
- return NGX_ERROR;
+ goto error;
}
- wev = c->write;
-
if (!wev->ready) {
return NGX_AGAIN;
}
@@ -948,6 +960,15 @@
return ngx_http_v2_state_skip_padded(h2c, pos, end);
}
+ r = stream->request;
+
+ if (r->reading_body && !r->request_body_no_buffering) {
+ ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
+ "skipping http2 DATA frame");
+
+ return ngx_http_v2_state_skip_padded(h2c, pos, end);
+ }
+
size = end - pos;
if (size >= h2c->state.length) {
@@ -955,7 +976,7 @@
stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG;
}
- r = stream->request;
+ h2c->payload_bytes += size;
if (r->request_body) {
rc = ngx_http_v2_process_request_body(r, pos, size, stream->in_closed);
@@ -1101,20 +1122,19 @@
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
}
- h2c->last_sid = h2c->state.sid;
-
- h2c->state.pool = ngx_create_pool(1024, h2c->connection->log);
- if (h2c->state.pool == NULL) {
- return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
- }
-
if (depend == h2c->state.sid) {
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
"client sent HEADERS frame for stream %ui "
"with incorrect dependency", h2c->state.sid);
- status = NGX_HTTP_V2_PROTOCOL_ERROR;
- goto rst_stream;
+ return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
+ }
+
+ h2c->last_sid = h2c->state.sid;
+
+ h2c->state.pool = ngx_create_pool(1024, h2c->connection->log);
+ if (h2c->state.pool == NULL) {
+ return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
}
h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
@@ -1843,28 +1863,7 @@
"client sent PRIORITY frame for stream %ui "
"with incorrect dependency", h2c->state.sid);
- node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);
-
- if (node && node->stream) {
- if (ngx_http_v2_terminate_stream(h2c, node->stream,
- NGX_HTTP_V2_PROTOCOL_ERROR)
- == NGX_ERROR)
- {
- return ngx_http_v2_connection_error(h2c,
- NGX_HTTP_V2_INTERNAL_ERROR);
- }
-
- } else {
- if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid,
- NGX_HTTP_V2_PROTOCOL_ERROR)
- == NGX_ERROR)
- {
- return ngx_http_v2_connection_error(h2c,
- NGX_HTTP_V2_INTERNAL_ERROR);
- }
- }
-
- return ngx_http_v2_state_complete(h2c, pos, end);
+ return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
}
node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 1);
@@ -2276,41 +2275,11 @@
h2c->state.sid, window);
if (window == 0) {
- if (h2c->state.sid == 0) {
- ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
- "client sent WINDOW_UPDATE frame "
- "with incorrect window increment 0");
-
- return ngx_http_v2_connection_error(h2c,
- NGX_HTTP_V2_PROTOCOL_ERROR);
- }
-
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
- "client sent WINDOW_UPDATE frame for stream %ui "
- "with incorrect window increment 0", h2c->state.sid);
+ "client sent WINDOW_UPDATE frame "
+ "with incorrect window increment 0");
- node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 0);
-
- if (node && node->stream) {
- if (ngx_http_v2_terminate_stream(h2c, node->stream,
- NGX_HTTP_V2_PROTOCOL_ERROR)
- == NGX_ERROR)
- {
- return ngx_http_v2_connection_error(h2c,
- NGX_HTTP_V2_INTERNAL_ERROR);
- }
-
- } else {
- if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid,
- NGX_HTTP_V2_PROTOCOL_ERROR)
- == NGX_ERROR)
- {
- return ngx_http_v2_connection_error(h2c,
- NGX_HTTP_V2_INTERNAL_ERROR);
- }
- }
-
- return ngx_http_v2_state_complete(h2c, pos, end);
+ return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_PROTOCOL_ERROR);
}
if (h2c->state.sid) {
@@ -2997,9 +2966,9 @@
"requested control frame is too large: %uz", length);
return NULL;
}
+#endif
frame->length = length;
-#endif
buf->last = ngx_http_v2_write_len_and_type(buf->pos, length, type);
@@ -3026,6 +2995,8 @@
frame->next = h2c->free_frames;
h2c->free_frames = frame;
+ h2c->total_bytes += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
+
return NGX_OK;
}
@@ -3811,7 +3782,8 @@
static void
ngx_http_v2_run_request(ngx_http_request_t *r)
{
- ngx_connection_t *fc;
+ ngx_connection_t *fc;
+ ngx_http_v2_connection_t *h2c;
fc = r->connection;
@@ -3843,6 +3815,10 @@
r->headers_in.chunked = 1;
}
+ h2c = r->stream->connection;
+
+ h2c->payload_bytes += r->request_length;
+
ngx_http_process_request(r);
failed:
@@ -4378,33 +4354,11 @@
}
} else if (!stream->in_closed) {
-#if 0
if (ngx_http_v2_send_rst_stream(h2c, node->id, NGX_HTTP_V2_NO_ERROR)
!= NGX_OK)
{
h2c->connection->error = 1;
}
-#else
- /*
- * At the time of writing at least the latest versions of Chrome
- * do not properly handle RST_STREAM with NO_ERROR status.
- *
- * See: https://bugs.chromium.org/p/chromium/issues/detail?id=603182
- *
- * As a workaround, the stream window is maximized before closing
- * the stream. This allows a client to send up to 2 GB of data
- * before getting blocked on flow control.
- */
-
- if (stream->recv_window < NGX_HTTP_V2_MAX_WINDOW
- && ngx_http_v2_send_window_update(h2c, node->id,
- NGX_HTTP_V2_MAX_WINDOW
- - stream->recv_window)
- != NGX_OK)
- {
- h2c->connection->error = 1;
- }
-#endif
}
}
diff --git a/src/http/v2/ngx_http_v2.h b/src/http/v2/ngx_http_v2.h
index 69d55d1..59ddf54 100644
--- a/src/http/v2/ngx_http_v2.h
+++ b/src/http/v2/ngx_http_v2.h
@@ -119,6 +119,9 @@
ngx_connection_t *connection;
ngx_http_connection_t *http_connection;
+ off_t total_bytes;
+ off_t payload_bytes;
+
ngx_uint_t processing;
ngx_uint_t frames;
ngx_uint_t idle;
diff --git a/src/http/v2/ngx_http_v2_filter_module.c b/src/http/v2/ngx_http_v2_filter_module.c
index f1618ae..5a38737 100644
--- a/src/http/v2/ngx_http_v2_filter_module.c
+++ b/src/http/v2/ngx_http_v2_filter_module.c
@@ -1886,6 +1886,8 @@
stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
+ frame->length;
+ h2c->payload_bytes += frame->length;
+
ngx_http_v2_handle_frame(stream, frame);
ngx_http_v2_handle_stream(h2c, stream);
@@ -1940,6 +1942,8 @@
stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
+ frame->length;
+ h2c->payload_bytes += frame->length;
+
ngx_http_v2_handle_frame(stream, frame);
ngx_http_v2_handle_stream(h2c, stream);
@@ -2033,6 +2037,8 @@
stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE;
+ h2c->payload_bytes += frame->length;
+
ngx_http_v2_handle_frame(stream, frame);
ngx_http_v2_handle_stream(h2c, stream);
@@ -2045,12 +2051,17 @@
ngx_http_v2_handle_frame(ngx_http_v2_stream_t *stream,
ngx_http_v2_out_frame_t *frame)
{
- ngx_http_request_t *r;
+ ngx_http_request_t *r;
+ ngx_http_v2_connection_t *h2c;
r = stream->request;
r->connection->sent += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
+ h2c = stream->connection;
+
+ h2c->total_bytes += NGX_HTTP_V2_FRAME_HEADER_SIZE + frame->length;
+
if (frame->fin) {
stream->out_closed = 1;
}
diff --git a/src/mail/ngx_mail_ssl_module.c b/src/mail/ngx_mail_ssl_module.c
index 5544f75..e193b29 100644
--- a/src/mail/ngx_mail_ssl_module.c
+++ b/src/mail/ngx_mail_ssl_module.c
@@ -388,7 +388,7 @@
if (conf->client_certificate.len == 0 && conf->verify != 3) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no ssl_client_certificate for ssl_client_verify");
+ "no ssl_client_certificate for ssl_verify_client");
return NGX_CONF_ERROR;
}
diff --git a/src/stream/ngx_stream_ssl_module.c b/src/stream/ngx_stream_ssl_module.c
index ec9524e..79f30a8 100644
--- a/src/stream/ngx_stream_ssl_module.c
+++ b/src/stream/ngx_stream_ssl_module.c
@@ -745,7 +745,7 @@
if (conf->client_certificate.len == 0 && conf->verify != 3) {
ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
- "no ssl_client_certificate for ssl_client_verify");
+ "no ssl_client_certificate for ssl_verify_client");
return NGX_CONF_ERROR;
}