From 65b2c00d624f17892c777f8fb5bb9c623cff5188 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Tue, 6 Nov 2018 16:29:35 +0300 Subject: [PATCH] HTTP/2: flood detection. Fixed uncontrolled memory growth in case peer is flooding us with some frames (e.g., SETTINGS and PING) and doesn't read data. Fix is to limit the number of allocated control frames. --- src/http/v2/ngx_http_v2.c | 12 +++++++++++- src/http/v2/ngx_http_v2.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c index 77ebb8474..17d7cad04 100644 --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -664,6 +664,7 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c) h2c->pool = NULL; h2c->free_frames = NULL; + h2c->frames = 0; h2c->free_fake_connections = NULL; #if (NGX_HTTP_SSL) @@ -2895,7 +2896,7 @@ ngx_http_v2_get_frame(ngx_http_v2_connection_t *h2c, size_t length, frame->blocked = 0; - } else { + } else if (h2c->frames < 10000) { pool = h2c->pool ? h2c->pool : h2c->connection->pool; frame = ngx_pcalloc(pool, sizeof(ngx_http_v2_out_frame_t)); @@ -2919,6 +2920,15 @@ ngx_http_v2_get_frame(ngx_http_v2_connection_t *h2c, size_t length, frame->last = frame->first; frame->handler = ngx_http_v2_frame_handler; + + h2c->frames++; + + } else { + ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0, + "http2 flood detected"); + + h2c->connection->error = 1; + return NULL; } #if (NGX_DEBUG) diff --git a/src/http/v2/ngx_http_v2.h b/src/http/v2/ngx_http_v2.h index ebd0e77c0..e8eaebb25 100644 --- a/src/http/v2/ngx_http_v2.h +++ b/src/http/v2/ngx_http_v2.h @@ -120,6 +120,7 @@ struct ngx_http_v2_connection_s { ngx_http_connection_t *http_connection; ngx_uint_t processing; + ngx_uint_t frames; ngx_uint_t pushing; ngx_uint_t concurrent_pushes;