Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mysql-test/main/mysql_client_test_comp-master.opt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
--loose-enable-performance-schema
--max-allowed-packet=32000000
--proxy-protocol-networks=::1/32,127.0.0.0/8,localhost
--proxy-protocol-networks=::1/32,127.0.0.0/8,localhost,2001:db8::6:6
--sequence=on
Comment on lines 1 to 4
2 changes: 1 addition & 1 deletion mysql-test/main/mysql_client_test_nonblock-master.opt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
--general-log --general-log-file=$MYSQLTEST_VARDIR/log/master.log --log-output=FILE,TABLE
--max-allowed-packet=32000000
--proxy-protocol-networks=::1,::ffff:127.0.0.1/97,localhost
--proxy-protocol-networks=::1,::ffff:127.0.0.1/97,localhost,2001:db8::6:6
--sequence=on
7 changes: 7 additions & 0 deletions sql/sql_connect.cc
Original file line number Diff line number Diff line change
Expand Up @@ -877,6 +877,13 @@ int thd_set_peer_addr(THD *thd,
{
int rc;

/* Free any previously resolved hostname before overwriting it. */
if (thd->main_security_ctx.host != my_localhost)
{
my_free((void *) thd->main_security_ctx.host);
thd->main_security_ctx.host= NULL;
}

rc = ip_to_hostname(addr,
thd->main_security_ctx.ip,
&thd->main_security_ctx.host,
Expand Down
79 changes: 79 additions & 0 deletions tests/mysql_client_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -20747,6 +20747,84 @@ static void test_proxy_header_ignore()
}


/*
MDEV-37556 memory leak in proxy protocol for non-loopback
connections.

Uses debug_dbug variable to set vio_peer_addr_fake_ipv6 etc
to emulate a remote connection
*/
static void test_proxy_header_dbug_remote_connection()
{
#ifndef DBUG_OFF
int rc;
MYSQL *m;
MYSQL_RES *result;
MYSQL_ROW row;
v2_proxy_header v2_header;
char addr_bin[16];
const char *proxy_ipv6 = "2001:db8::6:6";
int protocol= MYSQL_PROTOCOL_TCP;
Comment thread
vaintroub marked this conversation as resolved.

myheader("test_proxy_header_dbug_remote_connection");

/* Save and override debug_dbug so name resolution does not hit real DNS. */
rc= mysql_query(mysql,
"SET @save_debug_dbug = @@GLOBAL.debug_dbug");
myquery(rc);
rc= mysql_query(mysql,
"SET GLOBAL debug_dbug='+d,vio_peer_addr_fake_ipv6"
",getnameinfo_fake_ipv6,getaddrinfo_fake_good_ipv6'");
myquery(rc);

/* Create a user identified by the hostname that the debug points will produce. */
rc= mysql_query(mysql,
"CREATE USER 'u'@'santa.claus.ipv6.example.com' IDENTIFIED BY 'password'");
myquery(rc);

/* Build a v2 proxy header announcing proxy_ipv6 as the client address. */
memset(&v2_header, 0, sizeof(v2_header));
memcpy(v2_header.sig, "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A", 12);
v2_header.ver_cmd = (0x2 << 4) | 0x1; /* PROXY command */
v2_header.fam = 0x21; /* TCPv6 */
v2_header.len = htons(36);
inet_pton(AF_INET6, proxy_ipv6, addr_bin);
memcpy(v2_header.addr.ip6.src_addr, addr_bin, 16);
memcpy(v2_header.addr.ip6.dst_addr, addr_bin, 16);
Comment thread
vaintroub marked this conversation as resolved.
v2_header.addr.ip6.src_port = htons(2222);
v2_header.addr.ip6.dst_port = htons(3306);

m = mysql_client_init(NULL);
DIE_UNLESS(m != NULL);
mysql_optionsv(m, MARIADB_OPT_PROXY_HEADER, &v2_header, (size_t)52);
mysql_optionsv(m, MYSQL_OPT_PROTOCOL, &protocol);

if (!mysql_real_connect(m, opt_host, "u", "password", NULL, opt_port, NULL, 0))
DIE(0);

/* Verify that the server sees the proxied port, and fake hostname. */
rc= mysql_query(m,
"SELECT host FROM information_schema.processlist"
" WHERE ID = connection_id()");
DIE_UNLESS(!rc);
result= mysql_store_result(m);
DIE_UNLESS(result);
row= mysql_fetch_row(result);
DIE_UNLESS(strcmp(row[0], "santa.claus.ipv6.example.com:2222") == 0);
mysql_free_result(result);

mysql_close(m);

rc= mysql_query(mysql, "DROP USER 'u'@'santa.claus.ipv6.example.com'");
myquery(rc);

/* Restore debug_dbug to whatever it was before this test. */
rc= mysql_query(mysql, "SET GLOBAL debug_dbug = @save_debug_dbug");
myquery(rc);
#endif /* !DBUG_OFF */
}


static void test_proxy_header()
{
myheader("test_proxy_header");
Expand All @@ -20755,6 +20833,7 @@ static void test_proxy_header()
test_proxy_header_tcp("::ffff:192.0.2.1",2222);
test_proxy_header_localhost();
test_proxy_header_ignore();
test_proxy_header_dbug_remote_connection();
}


Expand Down