changeset 7377:d4448892a294

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.
author Ruslan Ermilov <ru@nginx.com>
date Tue, 06 Nov 2018 16:29:35 +0300
parents e5069816039b
children e7f19d268c72
files src/http/v2/ngx_http_v2.c src/http/v2/ngx_http_v2.h
diffstat 2 files changed, 12 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -662,6 +662,7 @@ ngx_http_v2_handle_connection(ngx_http_v
 
     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_connec
 
         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_connec
         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)
--- 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;