details: https://hg.nginx.org/nginx/rev/9f84f2e49c62 branches: changeset: 9237:9f84f2e49c62 user: Roman Arutyunyan <a...@nginx.com> date: Thu Apr 11 11:37:30 2024 +0400 description: Stream pass: limited the number of passes per connection.
Previously a cycle in pass configuration resulted in stack overflow. diffstat: src/stream/ngx_stream_pass_module.c | 51 +++++++++++++++++++++++++++++++++++++ 1 files changed, 51 insertions(+), 0 deletions(-) diffs (82 lines): diff -r 155c9093de9d -r 9f84f2e49c62 src/stream/ngx_stream_pass_module.c --- a/src/stream/ngx_stream_pass_module.c Wed Apr 10 09:38:10 2024 +0300 +++ b/src/stream/ngx_stream_pass_module.c Thu Apr 11 11:37:30 2024 +0400 @@ -10,6 +10,9 @@ #include <ngx_stream.h> +#define NGX_STREAM_PASS_MAX_PASSES 10 + + typedef struct { ngx_addr_t *addr; ngx_stream_complex_value_t *addr_value; @@ -17,6 +20,8 @@ typedef struct { static void ngx_stream_pass_handler(ngx_stream_session_t *s); +static ngx_int_t ngx_stream_pass_check_cycle(ngx_connection_t *c); +static void ngx_stream_pass_cleanup(void *data); static ngx_int_t ngx_stream_pass_match(ngx_listening_t *ls, ngx_addr_t *addr); static void *ngx_stream_pass_create_srv_conf(ngx_conf_t *cf); static char *ngx_stream_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); @@ -125,6 +130,10 @@ ngx_stream_pass_handler(ngx_stream_sessi ngx_log_debug1(NGX_LOG_DEBUG_STREAM, c->log, 0, "stream pass addr: \"%V\"", &addr->name); + if (ngx_stream_pass_check_cycle(c) != NGX_OK) { + goto failed; + } + ls = ngx_cycle->listening.elts; for (i = 0; i < ngx_cycle->listening.nelts; i++) { @@ -164,6 +173,48 @@ failed: static ngx_int_t +ngx_stream_pass_check_cycle(ngx_connection_t *c) +{ + ngx_uint_t *num; + ngx_pool_cleanup_t *cln; + + for (cln = c->pool->cleanup; cln; cln = cln->next) { + if (cln->handler != ngx_stream_pass_cleanup) { + continue; + } + + num = cln->data; + + if (++(*num) > NGX_STREAM_PASS_MAX_PASSES) { + ngx_log_error(NGX_LOG_ERR, c->log, 0, "stream pass cycle"); + return NGX_ERROR; + } + + return NGX_OK; + } + + cln = ngx_pool_cleanup_add(c->pool, sizeof(ngx_uint_t)); + if (cln == NULL) { + return NGX_ERROR; + } + + cln->handler = ngx_stream_pass_cleanup; + + num = cln->data; + *num = 1; + + return NGX_OK; +} + + +static void +ngx_stream_pass_cleanup(void *data) +{ + return; +} + + +static ngx_int_t ngx_stream_pass_match(ngx_listening_t *ls, ngx_addr_t *addr) { if (!ls->wildcard) { _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org https://mailman.nginx.org/mailman/listinfo/nginx-devel