Commit 26f03b0b authored by davi@moksha.com.br's avatar davi@moksha.com.br
Browse files

Merge moksha.local:/Users/davi/mysql/bugs/31669-5.0

into  moksha.local:/Users/davi/mysql/mysql-5.0-runtime
parents 6d15d42e dac55f09
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -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");

@@ -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])
@@ -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);
+94 −0
Original line number Diff line number Diff line
@@ -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
*/
@@ -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 }
};