mirror of
https://github.com/MariaDB/server.git
synced 2025-07-02 14:22:51 +03:00
Automerge MariaDB 5.1.44b release.
This commit is contained in:
@ -1413,3 +1413,19 @@ DROP USER 'user1';
|
|||||||
DROP USER 'user1'@'localhost';
|
DROP USER 'user1'@'localhost';
|
||||||
DROP USER 'user2';
|
DROP USER 'user2';
|
||||||
DROP DATABASE db1;
|
DROP DATABASE db1;
|
||||||
|
CREATE DATABASE db1;
|
||||||
|
CREATE DATABASE db2;
|
||||||
|
GRANT SELECT ON db1.* to 'testbug'@localhost;
|
||||||
|
USE db2;
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
USE test;
|
||||||
|
SELECT * FROM `../db2/tb2`;
|
||||||
|
ERROR 42S02: Table 'db1.../db2/tb2' doesn't exist
|
||||||
|
SELECT * FROM `../db2`.tb2;
|
||||||
|
ERROR 42000: SELECT command denied to user 'testbug'@'localhost' for table 'tb2'
|
||||||
|
SELECT * FROM `#mysql50#/../db2/tb2`;
|
||||||
|
ERROR 42S02: Table 'db1.#mysql50#/../db2/tb2' doesn't exist
|
||||||
|
DROP USER 'testbug'@localhost;
|
||||||
|
DROP TABLE db2.t1;
|
||||||
|
DROP DATABASE db1;
|
||||||
|
DROP DATABASE db2;
|
||||||
|
@ -1525,5 +1525,30 @@ DROP USER 'user1'@'localhost';
|
|||||||
DROP USER 'user2';
|
DROP USER 'user2';
|
||||||
DROP DATABASE db1;
|
DROP DATABASE db1;
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug #53371: COM_FIELD_LIST can be abused to bypass table level grants.
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE DATABASE db1;
|
||||||
|
CREATE DATABASE db2;
|
||||||
|
GRANT SELECT ON db1.* to 'testbug'@localhost;
|
||||||
|
USE db2;
|
||||||
|
CREATE TABLE t1 (a INT);
|
||||||
|
USE test;
|
||||||
|
connect (con1,localhost,testbug,,db1);
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
SELECT * FROM `../db2/tb2`;
|
||||||
|
--error ER_TABLEACCESS_DENIED_ERROR
|
||||||
|
SELECT * FROM `../db2`.tb2;
|
||||||
|
--error ER_NO_SUCH_TABLE
|
||||||
|
SELECT * FROM `#mysql50#/../db2/tb2`;
|
||||||
|
connection default;
|
||||||
|
disconnect con1;
|
||||||
|
DROP USER 'testbug'@localhost;
|
||||||
|
DROP TABLE db2.t1;
|
||||||
|
DROP DATABASE db1;
|
||||||
|
DROP DATABASE db2;
|
||||||
|
|
||||||
# Wait till we reached the initial number of concurrent sessions
|
# Wait till we reached the initial number of concurrent sessions
|
||||||
--source include/wait_until_count_sessions.inc
|
--source include/wait_until_count_sessions.inc
|
||||||
|
@ -2289,7 +2289,7 @@ void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form);
|
|||||||
int rename_file_ext(const char * from,const char * to,const char * ext);
|
int rename_file_ext(const char * from,const char * to,const char * ext);
|
||||||
bool check_db_name(LEX_STRING *db);
|
bool check_db_name(LEX_STRING *db);
|
||||||
bool check_column_name(const char *name);
|
bool check_column_name(const char *name);
|
||||||
bool check_table_name(const char *name, uint length);
|
bool check_table_name(const char *name, uint length, bool check_for_path_chars);
|
||||||
char *get_field(MEM_ROOT *mem, Field *field);
|
char *get_field(MEM_ROOT *mem, Field *field);
|
||||||
bool get_field(MEM_ROOT *mem, Field *field, class String *res);
|
bool get_field(MEM_ROOT *mem, Field *field, class String *res);
|
||||||
int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr);
|
int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr);
|
||||||
|
@ -972,7 +972,7 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
|
|||||||
part_elem->engine_type= default_engine_type;
|
part_elem->engine_type= default_engine_type;
|
||||||
}
|
}
|
||||||
if (check_table_name(part_elem->partition_name,
|
if (check_table_name(part_elem->partition_name,
|
||||||
strlen(part_elem->partition_name)))
|
strlen(part_elem->partition_name), FALSE))
|
||||||
{
|
{
|
||||||
my_error(ER_WRONG_PARTITION_NAME, MYF(0));
|
my_error(ER_WRONG_PARTITION_NAME, MYF(0));
|
||||||
goto end;
|
goto end;
|
||||||
@ -990,7 +990,7 @@ bool partition_info::check_partition_info(THD *thd, handlerton **eng_type,
|
|||||||
{
|
{
|
||||||
sub_elem= sub_it++;
|
sub_elem= sub_it++;
|
||||||
if (check_table_name(sub_elem->partition_name,
|
if (check_table_name(sub_elem->partition_name,
|
||||||
strlen(sub_elem->partition_name)))
|
strlen(sub_elem->partition_name), FALSE))
|
||||||
{
|
{
|
||||||
my_error(ER_WRONG_PARTITION_NAME, MYF(0));
|
my_error(ER_WRONG_PARTITION_NAME, MYF(0));
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -1334,6 +1334,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
system_charset_info, packet, db_length,
|
system_charset_info, packet, db_length,
|
||||||
thd->charset(), &dummy_errors);
|
thd->charset(), &dummy_errors);
|
||||||
db_buff[db_length]= '\0';
|
db_buff[db_length]= '\0';
|
||||||
|
if (check_table_name(db_buff, db_length, FALSE))
|
||||||
|
{
|
||||||
|
my_error(ER_WRONG_TABLE_NAME, MYF(0), db_buff);
|
||||||
|
break;
|
||||||
|
}
|
||||||
table_list.alias= table_list.table_name= db_buff;
|
table_list.alias= table_list.table_name= db_buff;
|
||||||
if (!(fields= (char *) thd->memdup(wildcard, query_length + 1)))
|
if (!(fields= (char *) thd->memdup(wildcard, query_length + 1)))
|
||||||
break;
|
break;
|
||||||
@ -6298,7 +6303,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
|||||||
DBUG_RETURN(0); // End of memory
|
DBUG_RETURN(0); // End of memory
|
||||||
alias_str= alias ? alias->str : table->table.str;
|
alias_str= alias ? alias->str : table->table.str;
|
||||||
if (!test(table_options & TL_OPTION_ALIAS) &&
|
if (!test(table_options & TL_OPTION_ALIAS) &&
|
||||||
check_table_name(table->table.str, table->table.length))
|
check_table_name(table->table.str, table->table.length, FALSE))
|
||||||
{
|
{
|
||||||
my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
|
my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
@ -435,7 +435,21 @@ uint tablename_to_filename(const char *from, char *to, uint to_length)
|
|||||||
DBUG_PRINT("enter", ("from '%s'", from));
|
DBUG_PRINT("enter", ("from '%s'", from));
|
||||||
|
|
||||||
if ((length= check_n_cut_mysql50_prefix(from, to, to_length)))
|
if ((length= check_n_cut_mysql50_prefix(from, to, to_length)))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Check if the name supplied is a valid mysql 5.0 name and
|
||||||
|
make the name a zero length string if it's not.
|
||||||
|
Note that just returning zero length is not enough :
|
||||||
|
a lot of places don't check the return value and expect
|
||||||
|
a zero terminated string.
|
||||||
|
*/
|
||||||
|
if (check_table_name(to, length, TRUE))
|
||||||
|
{
|
||||||
|
to[0]= 0;
|
||||||
|
length= 0;
|
||||||
|
}
|
||||||
DBUG_RETURN(length);
|
DBUG_RETURN(length);
|
||||||
|
}
|
||||||
length= strconvert(system_charset_info, from,
|
length= strconvert(system_charset_info, from,
|
||||||
&my_charset_filename, to, to_length, &errors);
|
&my_charset_filename, to, to_length, &errors);
|
||||||
if (check_if_legal_tablename(to) &&
|
if (check_if_legal_tablename(to) &&
|
||||||
|
@ -6149,7 +6149,7 @@ alter_list_item:
|
|||||||
{
|
{
|
||||||
MYSQL_YYABORT;
|
MYSQL_YYABORT;
|
||||||
}
|
}
|
||||||
if (check_table_name($3->table.str,$3->table.length) ||
|
if (check_table_name($3->table.str,$3->table.length, FALSE) ||
|
||||||
($3->db.str && check_db_name(&$3->db)))
|
($3->db.str && check_db_name(&$3->db)))
|
||||||
{
|
{
|
||||||
my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str);
|
my_error(ER_WRONG_TABLE_NAME, MYF(0), $3->table.str);
|
||||||
|
22
sql/table.cc
22
sql/table.cc
@ -494,6 +494,19 @@ inline bool is_system_table_name(const char *name, uint length)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Check if a string contains path elements
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline bool has_disabled_path_chars(const char *str)
|
||||||
|
{
|
||||||
|
for (; *str; str++)
|
||||||
|
if (*str == FN_EXTCHAR || *str == '/' || *str == '\\' || *str == '~' || *str == '@')
|
||||||
|
return TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read table definition from a binary / text based .frm file
|
Read table definition from a binary / text based .frm file
|
||||||
|
|
||||||
@ -548,7 +561,8 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags)
|
|||||||
This kind of tables must have been opened only by the
|
This kind of tables must have been opened only by the
|
||||||
my_open() above.
|
my_open() above.
|
||||||
*/
|
*/
|
||||||
if (strchr(share->table_name.str, '@') ||
|
if (has_disabled_path_chars(share->table_name.str) ||
|
||||||
|
has_disabled_path_chars(share->db.str) ||
|
||||||
!strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
|
!strncmp(share->db.str, MYSQL50_TABLE_NAME_PREFIX,
|
||||||
MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
|
MYSQL50_TABLE_NAME_PREFIX_LENGTH) ||
|
||||||
!strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
|
!strncmp(share->table_name.str, MYSQL50_TABLE_NAME_PREFIX,
|
||||||
@ -2718,7 +2732,6 @@ bool check_db_name(LEX_STRING *org_name)
|
|||||||
(name_length > NAME_CHAR_LEN)); /* purecov: inspected */
|
(name_length > NAME_CHAR_LEN)); /* purecov: inspected */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Allow anything as a table name, as long as it doesn't contain an
|
Allow anything as a table name, as long as it doesn't contain an
|
||||||
' ' at the end
|
' ' at the end
|
||||||
@ -2726,7 +2739,7 @@ bool check_db_name(LEX_STRING *org_name)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
bool check_table_name(const char *name, uint length)
|
bool check_table_name(const char *name, uint length, bool check_for_path_chars)
|
||||||
{
|
{
|
||||||
uint name_length= 0; // name length in symbols
|
uint name_length= 0; // name length in symbols
|
||||||
const char *end= name+length;
|
const char *end= name+length;
|
||||||
@ -2753,6 +2766,9 @@ bool check_table_name(const char *name, uint length)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (check_for_path_chars &&
|
||||||
|
(*name == '/' || *name == '\\' || *name == '~' || *name == FN_EXTCHAR))
|
||||||
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
name++;
|
name++;
|
||||||
name_length++;
|
name_length++;
|
||||||
|
@ -18092,6 +18092,50 @@ static void test_bug44495()
|
|||||||
DBUG_VOID_RETURN;
|
DBUG_VOID_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_bug53371()
|
||||||
|
{
|
||||||
|
int rc;
|
||||||
|
MYSQL_RES *result;
|
||||||
|
|
||||||
|
myheader("test_bug53371");
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
|
||||||
|
myquery(rc);
|
||||||
|
rc= mysql_query(mysql, "DROP DATABASE IF EXISTS bug53371");
|
||||||
|
myquery(rc);
|
||||||
|
rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "CREATE TABLE t1 (a INT)");
|
||||||
|
myquery(rc);
|
||||||
|
rc= mysql_query(mysql, "CREATE DATABASE bug53371");
|
||||||
|
myquery(rc);
|
||||||
|
rc= mysql_query(mysql, "GRANT SELECT ON bug53371.* to 'testbug'@localhost");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_change_user(mysql, "testbug", NULL, "bug53371");
|
||||||
|
myquery(rc);
|
||||||
|
|
||||||
|
rc= mysql_query(mysql, "SHOW COLUMNS FROM client_test_db.t1");
|
||||||
|
DIE_UNLESS(rc);
|
||||||
|
DIE_UNLESS(mysql_errno(mysql) == 1142);
|
||||||
|
|
||||||
|
result= mysql_list_fields(mysql, "../client_test_db/t1", NULL);
|
||||||
|
DIE_IF(result);
|
||||||
|
|
||||||
|
result= mysql_list_fields(mysql, "#mysql50#/../client_test_db/t1", NULL);
|
||||||
|
DIE_IF(result);
|
||||||
|
|
||||||
|
rc= mysql_change_user(mysql, opt_user, opt_password, current_db);
|
||||||
|
myquery(rc);
|
||||||
|
rc= mysql_query(mysql, "DROP TABLE t1");
|
||||||
|
myquery(rc);
|
||||||
|
rc= mysql_query(mysql, "DROP DATABASE bug53371");
|
||||||
|
myquery(rc);
|
||||||
|
rc= mysql_query(mysql, "DROP USER 'testbug'@localhost");
|
||||||
|
myquery(rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Read and parse arguments and MySQL options from my.cnf
|
Read and parse arguments and MySQL options from my.cnf
|
||||||
*/
|
*/
|
||||||
@ -18401,6 +18445,7 @@ static struct my_tests_st my_tests[]= {
|
|||||||
{ "test_bug30472", test_bug30472 },
|
{ "test_bug30472", test_bug30472 },
|
||||||
{ "test_bug20023", test_bug20023 },
|
{ "test_bug20023", test_bug20023 },
|
||||||
{ "test_bug45010", test_bug45010 },
|
{ "test_bug45010", test_bug45010 },
|
||||||
|
{ "test_bug53371", test_bug53371 },
|
||||||
{ "test_bug31418", test_bug31418 },
|
{ "test_bug31418", test_bug31418 },
|
||||||
{ "test_bug31669", test_bug31669 },
|
{ "test_bug31669", test_bug31669 },
|
||||||
{ "test_bug28386", test_bug28386 },
|
{ "test_bug28386", test_bug28386 },
|
||||||
|
Reference in New Issue
Block a user