Skip to content
Merged
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
35 changes: 35 additions & 0 deletions mysql-test/suite/plugins/r/mdev38431.result
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#
# Setup
#
INSTALL PLUGIN IF NOT EXISTS cleartext_plugin_server SONAME '';
Warnings:
Note 1968 Plugin 'cleartext_plugin_server' already installed
CREATE DATABASE mdev38431_db;
#
# Test 1: Short password - baseline test
#
CREATE USER shortuser IDENTIFIED VIA cleartext_plugin_server USING 'secret';
GRANT ALL ON *.* TO shortuser;
db
mdev38431_db
#
# Test 2: Long password 260 bytes (triggers 3-byte LENENC)
# Before fix: ERROR 1044 Access denied to database 'X' (garbage char)
# After fix: Connects to mdev38431_db correctly
#
CREATE USER longuser IDENTIFIED VIA cleartext_plugin_server USING 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
GRANT ALL ON *.* TO longuser;
db
mdev38431_db
#
# Test 3: Even longer password 500 bytes
#
CREATE USER verylonguser IDENTIFIED VIA cleartext_plugin_server USING 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';
GRANT ALL ON *.* TO verylonguser;
db
mdev38431_db
#
# Cleanup
#
DROP USER shortuser, longuser, verylonguser;
DROP DATABASE mdev38431_db;
59 changes: 59 additions & 0 deletions mysql-test/suite/plugins/t/mdev38431.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#
# MDEV-38431: Auth Switch with Long Password Corrupts Database Name
#
# When password >= 251 bytes with CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA,
# the length is encoded in 3 bytes (0xFC + 2 bytes). The server incorrectly
# calculated the database pointer, causing connection to wrong database.
#
# Fix: Use 'passwd + passwd_len' instead of 'db + passwd_len + 1'
#

--source include/not_embedded.inc
--source include/have_plugin_auth.inc

--echo #
--echo # Setup
--echo #
eval INSTALL PLUGIN IF NOT EXISTS cleartext_plugin_server SONAME '$PLUGIN_AUTH';
CREATE DATABASE mdev38431_db;

--echo #
--echo # Test 1: Short password - baseline test
--echo #
CREATE USER shortuser IDENTIFIED VIA cleartext_plugin_server USING 'secret';
GRANT ALL ON *.* TO shortuser;

# Connect with short password and verify database
--exec $MYSQL -h 127.0.0.1 -P $MASTER_MYPORT --default-auth=mysql_clear_password -u shortuser -p"secret" --database=mdev38431_db -e "SELECT DATABASE() AS db"

--echo #
--echo # Test 2: Long password 260 bytes (triggers 3-byte LENENC)
--echo # Before fix: ERROR 1044 Access denied to database 'X' (garbage char)
--echo # After fix: Connects to mdev38431_db correctly
--echo #

# Create password with 260 'a' characters
--let $long_pwd=`SELECT REPEAT('a', 260)`
eval CREATE USER longuser IDENTIFIED VIA cleartext_plugin_server USING '$long_pwd';
GRANT ALL ON *.* TO longuser;

# This connection uses --default-auth=mysql_clear_password to trigger auth switch
# With a password >= 251 bytes, the client sends password length in 3-byte format
# The bug caused the server to read database name from wrong offset
--exec $MYSQL -h 127.0.0.1 -P $MASTER_MYPORT --default-auth=mysql_clear_password -u longuser -p"$long_pwd" --database=mdev38431_db -e "SELECT DATABASE() AS db"

--echo #
--echo # Test 3: Even longer password 500 bytes
--echo #
--let $very_long_pwd=`SELECT REPEAT('b', 500)`
eval CREATE USER verylonguser IDENTIFIED VIA cleartext_plugin_server USING '$very_long_pwd';
GRANT ALL ON *.* TO verylonguser;

--exec $MYSQL -h 127.0.0.1 -P $MASTER_MYPORT --default-auth=mysql_clear_password -u verylonguser -p"$very_long_pwd" --database=mdev38431_db -e "SELECT DATABASE() AS db"

--echo #
--echo # Cleanup
--echo #
DROP USER shortuser, longuser, verylonguser;
DROP DATABASE mdev38431_db;
# Note: Do not uninstall cleartext_plugin_server as it was pre-loaded by MTR
22 changes: 14 additions & 8 deletions sql/sql_acl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13846,25 +13846,31 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio,
Cast *passwd to an unsigned char, so that it doesn't extend the sign for
*passwd > 127 and become 2**32-127+ after casting to uint.
*/
ulonglong len;
size_t passwd_len;

if (!(thd->client_capabilities & CLIENT_SECURE_CONNECTION))
len= strlen(passwd);
{
passwd_len= strlen(passwd);
db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
passwd + passwd_len + 1 : 0; /* +1 to skip null terminator */
}
else if (!(thd->client_capabilities & CLIENT_PLUGIN_AUTH_LENENC_CLIENT_DATA))
len= (uchar)(*passwd++);
{
passwd_len= (uchar)(*passwd++);
db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
passwd + passwd_len : 0;
}
else
{
len= safe_net_field_length_ll((uchar**)&passwd,
ulonglong len= safe_net_field_length_ll((uchar**)&passwd,
net->read_pos + pkt_len - (uchar*)passwd);
if (len > pkt_len)
return packet_error;
passwd_len= (size_t)len;
db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
passwd + passwd_len : 0;
}

passwd_len= (size_t)len;
db= thd->client_capabilities & CLIENT_CONNECT_WITH_DB ?
db + passwd_len + 1 : 0;

if (passwd == NULL ||
passwd + passwd_len + MY_TEST(db) > (char*) net->read_pos + pkt_len)
return packet_error;
Expand Down