From caac9d7f9493b0e5798afb0b9deb23af114bbc0d Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Thu, 3 Sep 2026 14:08:55 +0200 Subject: [PATCH] MDEV-40878 avoid repeated parsing of PROXY headers Do not parse multiple proxy headers. The protocol spec says the header is at the beginning of a connection, so there could only be one. According to example in the spec, in multi-layer scenarios, where several proxies are involved between client and backend, the intermediate proxy is supposed to be configured to replace the existing header. Thus multiple headers are not expected. --- sql/net_serv.cc | 18 ++++++++++++------ tests/mysql_client_test.c | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/sql/net_serv.cc b/sql/net_serv.cc index d3388bb2f62fe..5940318c6629c 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -986,6 +986,7 @@ my_real_read(NET *net, size_t *complen, size_t length; uint i,retry_count=0; ulong len=packet_error; + bool proxy_parsed= false; my_bool expect_error_packet __attribute__((unused))= 0; thr_alarm_t alarmed; #ifndef NO_ALARM @@ -1253,16 +1254,21 @@ my_real_read(NET *net, size_t *complen, packets_out_of_order: { - switch (handle_proxy_header(net)) { - case ABORT: + if (!proxy_parsed) + { + switch (handle_proxy_header(net)) + { + case ABORT: /* error happened, message is already written. */ len= packet_error; - goto end; - case RETRY: + goto end; + case RETRY: + proxy_parsed= true; goto retry; - case IGNORE: + case IGNORE: break; - } + } + } DBUG_PRINT("error", ("Packets out of order (Found: %d, expected %u)", diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index ef8f9c3d34a86..e0d818300ca59 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -20786,6 +20786,23 @@ static void test_proxy_header_limits() mysql_close(m); } +/* Test that connection fails with multiple proxy headers (MDEV-40878) */ +static void test_proxy_header_multiple() +{ + MYSQL *m; + const char header[]= "PROXY TCP4 192.0.2.1 127.0.0.1 12345 3306\r\n" + "PROXY TCP4 192.0.2.2 127.0.0.1 12346 3306\r\n"; + myheader("test_proxy_header_multiple"); + + m = mysql_client_init(NULL); + DIE_UNLESS(m); + mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, header, sizeof(header)-1); + + /* Connection should fail, second proxy header is interpreted as packet error */ + DIE_UNLESS(mysql_real_connect(m, opt_host, "root", "", NULL, opt_port, opt_unix_socket, 0) == NULL); + mysql_close(m); +} + /* MDEV-37556 memory leak in proxy protocol for non-loopback @@ -21095,6 +21112,7 @@ static void test_proxy_header() test_proxy_header_localhost(); test_proxy_header_ignore(); test_proxy_header_limits(); + test_proxy_header_multiple(); test_proxy_header_dbug_remote_connection(); test_proxy_header_connect_errors_reset(); test_proxy_header_proxy_host_connect_errors_reset();