Commit 38b3218c authored by Sergei Golubchik's avatar Sergei Golubchik

merged

parents 5eae48c9 212d78ef
...@@ -36,4 +36,4 @@ event-config.h: $(top_builddir)/include/config.h ...@@ -36,4 +36,4 @@ event-config.h: $(top_builddir)/include/config.h
-e 's/#ifndef /#ifndef _EVENT_/' < $(top_builddir)/include/config.h >> $@ -e 's/#ifndef /#ifndef _EVENT_/' < $(top_builddir)/include/config.h >> $@
echo "#endif" >> $@ echo "#endif" >> $@
AM_CPPFLAGS = -Icompat -I$(top_srcdir)/include AM_CPPFLAGS = -I$(srcdir)/compat -I$(top_srcdir)/include
...@@ -1414,3 +1414,19 @@ DROP USER 'user1'; ...@@ -1414,3 +1414,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'; ...@@ -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
...@@ -56,22 +56,22 @@ SET(pkgdatadir ${prefix}/share) ...@@ -56,22 +56,22 @@ SET(pkgdatadir ${prefix}/share)
SET(localstatedir ${prefix}/data) SET(localstatedir ${prefix}/data)
CONFIGURE_FILE(mysql_config.pl.in CONFIGURE_FILE(mysql_config.pl.in
scripts/mysql_config.pl ESCAPE_QUOTES @ONLY) ${CMAKE_BINARY_DIR}/scripts/mysql_config.pl ESCAPE_QUOTES @ONLY)
CONFIGURE_FILE(mysql_convert_table_format.sh CONFIGURE_FILE(mysql_convert_table_format.sh
scripts/mysql_convert_table_format.pl ESCAPE_QUOTES @ONLY) ${CMAKE_BINARY_DIR}/scripts/mysql_convert_table_format.pl ESCAPE_QUOTES @ONLY)
CONFIGURE_FILE(mysql_install_db.pl.in CONFIGURE_FILE(mysql_install_db.pl.in
scripts/mysql_install_db.pl ESCAPE_QUOTES @ONLY) ${CMAKE_BINARY_DIR}/scripts/mysql_install_db.pl ESCAPE_QUOTES @ONLY)
CONFIGURE_FILE(mysql_secure_installation.pl.in CONFIGURE_FILE(mysql_secure_installation.pl.in
scripts/mysql_secure_installation.pl ESCAPE_QUOTES @ONLY) ${CMAKE_BINARY_DIR}/scripts/mysql_secure_installation.pl ESCAPE_QUOTES @ONLY)
CONFIGURE_FILE(mysqld_multi.sh CONFIGURE_FILE(mysqld_multi.sh
scripts/mysqld_multi.pl ESCAPE_QUOTES @ONLY) ${CMAKE_BINARY_DIR}/scripts/mysqld_multi.pl ESCAPE_QUOTES @ONLY)
CONFIGURE_FILE(mysqldumpslow.sh CONFIGURE_FILE(mysqldumpslow.sh
scripts/mysqldumpslow.pl ESCAPE_QUOTES @ONLY) ${CMAKE_BINARY_DIR}/scripts/mysqldumpslow.pl ESCAPE_QUOTES @ONLY)
CONFIGURE_FILE(mysqlhotcopy.sh CONFIGURE_FILE(mysqlhotcopy.sh
scripts/mysqlhotcopy.pl ESCAPE_QUOTES @ONLY) ${CMAKE_BINARY_DIR}/scripts/mysqlhotcopy.pl ESCAPE_QUOTES @ONLY)
...@@ -72,7 +72,6 @@ sub main ...@@ -72,7 +72,6 @@ sub main
print "in MySQL 5.6. Please use --defaults-extra-file instead\n"; print "in MySQL 5.6. Please use --defaults-extra-file instead\n";
} }
} }
}
foreach (@defaults_options) foreach (@defaults_options)
{ {
......
...@@ -2339,7 +2339,7 @@ void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form); ...@@ -2339,7 +2339,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, ...@@ -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, ...@@ -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;
......
...@@ -1270,6 +1270,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -1270,6 +1270,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;
...@@ -6276,7 +6281,7 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ...@@ -6276,7 +6281,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);
......
...@@ -10991,6 +10991,11 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table, ...@@ -10991,6 +10991,11 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table,
if (table->s->db_type() != heap_hton || if (table->s->db_type() != heap_hton ||
error != HA_ERR_RECORD_FILE_FULL) error != HA_ERR_RECORD_FILE_FULL)
{ {
/*
We don't want this error to be converted to a warning, e.g. in case of
INSERT IGNORE ... SELECT.
*/
thd->fatal_error();
table->file->print_error(error,MYF(0)); table->file->print_error(error,MYF(0));
DBUG_RETURN(1); DBUG_RETURN(1);
} }
......
...@@ -428,7 +428,21 @@ uint tablename_to_filename(const char *from, char *to, uint to_length) ...@@ -428,7 +428,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) &&
......
...@@ -6345,7 +6345,7 @@ alter_list_item: ...@@ -6345,7 +6345,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);
......
...@@ -501,6 +501,19 @@ inline bool is_system_table_name(const char *name, uint length) ...@@ -501,6 +501,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
...@@ -555,7 +568,8 @@ int open_table_def(THD *thd, TABLE_SHARE *share, uint db_flags) ...@@ -555,7 +568,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,
...@@ -3161,7 +3175,6 @@ bool check_db_name(LEX_STRING *org_name) ...@@ -3161,7 +3175,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
...@@ -3169,7 +3182,7 @@ bool check_db_name(LEX_STRING *org_name) ...@@ -3169,7 +3182,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;
...@@ -3196,6 +3209,9 @@ bool check_table_name(const char *name, uint length) ...@@ -3196,6 +3209,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++;
......
...@@ -18093,6 +18093,50 @@ static void test_bug44495() ...@@ -18093,6 +18093,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
*/ */
...@@ -18402,6 +18446,7 @@ static struct my_tests_st my_tests[]= { ...@@ -18402,6 +18446,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 },
......
...@@ -16,12 +16,14 @@ fi ...@@ -16,12 +16,14 @@ fi
set -x set -x
win/configure-mariadb.sh if [ "x_$1" != "x_-nobuild" ]; then
win/configure-mariadb.sh
cmake -G "Visual Studio 9 2008" cmake -G "Visual Studio 9 2008"
devenv.com MySQL.sln /build RelWithDebInfo devenv.com MySQL.sln /build RelWithDebInfo
devenv.com MySQL.sln /build Debug devenv.com MySQL.sln /build Debug
fi
# TODO extract version number # TODO extract version number
VER=`cat configure.in | VER=`cat configure.in |
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment