Sophie

Sophie

distrib > Mandriva > 2008.0 > x86_64 > media > main-testing-src > by-pkgid > adf83d37405e61716c565e6e16f370ea > files > 23

mysql-5.0.45-7.3mdv2008.0.src.rpm

diff -Naurp mysql-5.0.45/libmysql/libmysql.c mysql-5.0.45.oden/libmysql/libmysql.c
--- mysql-5.0.45/libmysql/libmysql.c	2007-07-04 15:05:53.000000000 +0200
+++ mysql-5.0.45.oden/libmysql/libmysql.c	2008-01-25 13:22:03.000000000 +0100
@@ -693,7 +693,8 @@ int cli_read_change_user_result(MYSQL *m
 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");
 
@@ -703,7 +704,7 @@ my_bool	STDCALL mysql_change_user(MYSQL 
     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])
@@ -723,7 +724,7 @@ my_bool	STDCALL mysql_change_user(MYSQL 
   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);
diff -Naurp mysql-5.0.45/tests/mysql_client_test.c mysql-5.0.45.oden/tests/mysql_client_test.c
--- mysql-5.0.45/tests/mysql_client_test.c	2007-07-04 15:05:54.000000000 +0200
+++ mysql-5.0.45.oden/tests/mysql_client_test.c	2008-01-25 13:29:36.000000000 +0100
@@ -15680,6 +15680,99 @@ static void test_bug28934()
 }
 
 
+
+/**
+  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
 */
@@ -15963,6 +16056,7 @@ static struct my_tests_st my_tests[]= {
   { "test_bug27876", test_bug27876 },
   { "test_bug28505", test_bug28505 },
   { "test_bug28934", test_bug28934 },
+  { "test_bug31669", test_bug31669 },
   { 0, 0 }
 };
 
diff -Naurp mysql-5.0.45/tests/mysql_client_test.c.diff mysql-5.0.45.oden/tests/mysql_client_test.c.diff
--- mysql-5.0.45/tests/mysql_client_test.c.diff	1970-01-01 01:00:00.000000000 +0100
+++ mysql-5.0.45.oden/tests/mysql_client_test.c.diff	2008-01-25 13:25:00.000000000 +0100
@@ -0,0 +1,115 @@
+diff -Naurp mysql-5.0.45/tests/mysql_client_test.c mysql-5.0.45.oden/tests/mysql_client_test.c
+--- mysql-5.0.45/tests/mysql_client_test.c	2007-07-04 15:05:54.000000000 +0200
++++ mysql-5.0.45.oden/tests/mysql_client_test.c	2008-01-25 13:25:17.000000000 +0100
+@@ -15680,6 +15680,99 @@ static void test_bug28934()
+ }
+ 
+ 
++
++/**
++  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
+ */
+@@ -15963,10 +16056,10 @@ static struct my_tests_st my_tests[]= {
+   { "test_bug27876", test_bug27876 },
+   { "test_bug28505", test_bug28505 },
+   { "test_bug28934", test_bug28934 },
++  { "test_bug31669", test_bug31669 },
+   { 0, 0 }
+ };
+ 
+-
+ static my_bool
+ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+                char *argument)