Loading libmysql/libmysql.c +4 −3 Original line number Diff line number Diff line Loading @@ -706,7 +706,8 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd) my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, const char *passwd, const char *db) { char buff[512],*end=buff; char buff[USERNAME_LENGTH+SCRAMBLED_PASSWORD_CHAR_LENGTH+NAME_LEN+2]; char *end= buff; int rc; DBUG_ENTER("mysql_change_user"); Loading @@ -716,7 +717,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, passwd=""; /* Store user into the buffer */ end=strmov(end,user)+1; end= strmake(end, user, USERNAME_LENGTH) + 1; /* write scrambled password according to server capabilities */ if (passwd[0]) Loading @@ -736,7 +737,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, else *end++= '\0'; /* empty password */ /* Add database if needed */ end= strmov(end, db ? db : "") + 1; end= strmake(end, db ? db : "", NAME_LEN) + 1; /* Write authentication package */ simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (end-buff),1); Loading tests/mysql_client_test.c +94 −0 Original line number Diff line number Diff line Loading @@ -15864,6 +15864,99 @@ static void test_bug29306() DBUG_VOID_RETURN; } /** Bug#31669 Buffer overflow in mysql_change_user() */ #define LARGE_BUFFER_SIZE 2048 static void test_bug31669() { int rc; static char buff[LARGE_BUFFER_SIZE+1]; #ifndef EMBEDDED_LIBRARY static char user[USERNAME_LENGTH+1]; static char db[NAME_LEN+1]; static char query[LARGE_BUFFER_SIZE*2]; #endif DBUG_ENTER("test_bug31669"); myheader("test_bug31669"); rc= mysql_change_user(mysql, NULL, NULL, NULL); DIE_UNLESS(rc); rc= mysql_change_user(mysql, "", "", ""); DIE_UNLESS(rc); memset(buff, 'a', sizeof(buff)); rc= mysql_change_user(mysql, buff, buff, buff); DIE_UNLESS(rc); rc = mysql_change_user(mysql, opt_user, opt_password, current_db); DIE_UNLESS(!rc); #ifndef EMBEDDED_LIBRARY memset(db, 'a', sizeof(db)); db[NAME_LEN]= 0; strxmov(query, "CREATE DATABASE IF NOT EXISTS ", db, NullS); rc= mysql_query(mysql, query); myquery(rc); memset(user, 'b', sizeof(user)); user[USERNAME_LENGTH]= 0; memset(buff, 'c', sizeof(buff)); buff[LARGE_BUFFER_SIZE]= 0; strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'%' IDENTIFIED BY " "'", buff, "' WITH GRANT OPTION", NullS); rc= mysql_query(mysql, query); myquery(rc); rc= mysql_query(mysql, "FLUSH PRIVILEGES"); myquery(rc); rc= mysql_change_user(mysql, user, buff, db); DIE_UNLESS(!rc); user[USERNAME_LENGTH-1]= 'a'; rc= mysql_change_user(mysql, user, buff, db); DIE_UNLESS(rc); user[USERNAME_LENGTH-1]= 'b'; buff[LARGE_BUFFER_SIZE-1]= 'd'; rc= mysql_change_user(mysql, user, buff, db); DIE_UNLESS(rc); buff[LARGE_BUFFER_SIZE-1]= 'c'; db[NAME_LEN-1]= 'e'; rc= mysql_change_user(mysql, user, buff, db); DIE_UNLESS(rc); db[NAME_LEN-1]= 'a'; rc= mysql_change_user(mysql, user, buff, db); DIE_UNLESS(!rc); rc= mysql_change_user(mysql, user + 1, buff + 1, db + 1); DIE_UNLESS(rc); rc = mysql_change_user(mysql, opt_user, opt_password, current_db); DIE_UNLESS(!rc); strxmov(query, "DROP DATABASE ", db, NullS); rc= mysql_query(mysql, query); myquery(rc); strxmov(query, "DELETE FROM mysql.user WHERE User='", user, "'", NullS); rc= mysql_query(mysql, query); myquery(rc); DIE_UNLESS(mysql_affected_rows(mysql) == 1); #endif DBUG_VOID_RETURN; } /* Read and parse arguments and MySQL options from my.cnf */ Loading Loading @@ -16156,6 +16249,7 @@ static struct my_tests_st my_tests[]= { { "test_bug27592", test_bug27592 }, { "test_bug29948", test_bug29948 }, { "test_bug29306", test_bug29306 }, { "test_bug31669", test_bug31669 }, { 0, 0 } }; Loading Loading
libmysql/libmysql.c +4 −3 Original line number Diff line number Diff line Loading @@ -706,7 +706,8 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd) my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, const char *passwd, const char *db) { char buff[512],*end=buff; char buff[USERNAME_LENGTH+SCRAMBLED_PASSWORD_CHAR_LENGTH+NAME_LEN+2]; char *end= buff; int rc; DBUG_ENTER("mysql_change_user"); Loading @@ -716,7 +717,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, passwd=""; /* Store user into the buffer */ end=strmov(end,user)+1; end= strmake(end, user, USERNAME_LENGTH) + 1; /* write scrambled password according to server capabilities */ if (passwd[0]) Loading @@ -736,7 +737,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, else *end++= '\0'; /* empty password */ /* Add database if needed */ end= strmov(end, db ? db : "") + 1; end= strmake(end, db ? db : "", NAME_LEN) + 1; /* Write authentication package */ simple_command(mysql,COM_CHANGE_USER, buff,(ulong) (end-buff),1); Loading
tests/mysql_client_test.c +94 −0 Original line number Diff line number Diff line Loading @@ -15864,6 +15864,99 @@ static void test_bug29306() DBUG_VOID_RETURN; } /** Bug#31669 Buffer overflow in mysql_change_user() */ #define LARGE_BUFFER_SIZE 2048 static void test_bug31669() { int rc; static char buff[LARGE_BUFFER_SIZE+1]; #ifndef EMBEDDED_LIBRARY static char user[USERNAME_LENGTH+1]; static char db[NAME_LEN+1]; static char query[LARGE_BUFFER_SIZE*2]; #endif DBUG_ENTER("test_bug31669"); myheader("test_bug31669"); rc= mysql_change_user(mysql, NULL, NULL, NULL); DIE_UNLESS(rc); rc= mysql_change_user(mysql, "", "", ""); DIE_UNLESS(rc); memset(buff, 'a', sizeof(buff)); rc= mysql_change_user(mysql, buff, buff, buff); DIE_UNLESS(rc); rc = mysql_change_user(mysql, opt_user, opt_password, current_db); DIE_UNLESS(!rc); #ifndef EMBEDDED_LIBRARY memset(db, 'a', sizeof(db)); db[NAME_LEN]= 0; strxmov(query, "CREATE DATABASE IF NOT EXISTS ", db, NullS); rc= mysql_query(mysql, query); myquery(rc); memset(user, 'b', sizeof(user)); user[USERNAME_LENGTH]= 0; memset(buff, 'c', sizeof(buff)); buff[LARGE_BUFFER_SIZE]= 0; strxmov(query, "GRANT ALL PRIVILEGES ON *.* TO '", user, "'@'%' IDENTIFIED BY " "'", buff, "' WITH GRANT OPTION", NullS); rc= mysql_query(mysql, query); myquery(rc); rc= mysql_query(mysql, "FLUSH PRIVILEGES"); myquery(rc); rc= mysql_change_user(mysql, user, buff, db); DIE_UNLESS(!rc); user[USERNAME_LENGTH-1]= 'a'; rc= mysql_change_user(mysql, user, buff, db); DIE_UNLESS(rc); user[USERNAME_LENGTH-1]= 'b'; buff[LARGE_BUFFER_SIZE-1]= 'd'; rc= mysql_change_user(mysql, user, buff, db); DIE_UNLESS(rc); buff[LARGE_BUFFER_SIZE-1]= 'c'; db[NAME_LEN-1]= 'e'; rc= mysql_change_user(mysql, user, buff, db); DIE_UNLESS(rc); db[NAME_LEN-1]= 'a'; rc= mysql_change_user(mysql, user, buff, db); DIE_UNLESS(!rc); rc= mysql_change_user(mysql, user + 1, buff + 1, db + 1); DIE_UNLESS(rc); rc = mysql_change_user(mysql, opt_user, opt_password, current_db); DIE_UNLESS(!rc); strxmov(query, "DROP DATABASE ", db, NullS); rc= mysql_query(mysql, query); myquery(rc); strxmov(query, "DELETE FROM mysql.user WHERE User='", user, "'", NullS); rc= mysql_query(mysql, query); myquery(rc); DIE_UNLESS(mysql_affected_rows(mysql) == 1); #endif DBUG_VOID_RETURN; } /* Read and parse arguments and MySQL options from my.cnf */ Loading Loading @@ -16156,6 +16249,7 @@ static struct my_tests_st my_tests[]= { { "test_bug27592", test_bug27592 }, { "test_bug29948", test_bug29948 }, { "test_bug29306", test_bug29306 }, { "test_bug31669", test_bug31669 }, { 0, 0 } }; Loading