[nginx] Stream pass: limited the number of passes per connection.
Roman Arutyunyan
arut at nginx.com
Thu Apr 11 10:49:33 UTC 2024
details: https://hg.nginx.org/nginx/rev/9f84f2e49c62
branches:
changeset: 9237:9f84f2e49c62
user: Roman Arutyunyan <arut at 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) {
More information about the nginx-devel
mailing list