Bug #25717383: MYSQLDUMP MAY EXECUTE ANY ARBITRARY QUERY
While writing comments if database object names has a new line character, then next line is considered a command, rather than a comment. This patch fixes the way comments are constructed in mysqldump.
This commit is contained in:
parent
d8328690d9
commit
70766bec91
@ -549,6 +549,7 @@ static int dump_tablespaces_for_databases(char** databases);
|
|||||||
static int dump_tablespaces(char* ts_where);
|
static int dump_tablespaces(char* ts_where);
|
||||||
static void print_comment(FILE *sql_file, my_bool is_error, const char *format,
|
static void print_comment(FILE *sql_file, my_bool is_error, const char *format,
|
||||||
...);
|
...);
|
||||||
|
static const char* fix_identifier_with_newline(char*);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -649,7 +650,7 @@ static void write_header(FILE *sql_file, char *db_name)
|
|||||||
MACHINE_TYPE);
|
MACHINE_TYPE);
|
||||||
print_comment(sql_file, 0, "-- Host: %s Database: %s\n",
|
print_comment(sql_file, 0, "-- Host: %s Database: %s\n",
|
||||||
current_host ? current_host : "localhost",
|
current_host ? current_host : "localhost",
|
||||||
db_name ? db_name : "");
|
db_name ? fix_identifier_with_newline(db_name) : "");
|
||||||
print_comment(sql_file, 0,
|
print_comment(sql_file, 0,
|
||||||
"-- ------------------------------------------------------\n"
|
"-- ------------------------------------------------------\n"
|
||||||
);
|
);
|
||||||
@ -1981,6 +1982,30 @@ static void print_comment(FILE *sql_file, my_bool is_error, const char *format,
|
|||||||
print_xml_comment(sql_file, strlen(comment_buff), comment_buff);
|
print_xml_comment(sql_file, strlen(comment_buff), comment_buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
This function accepts object names and prefixes -- wherever \n
|
||||||
|
character is found.
|
||||||
|
|
||||||
|
@param[in] object_name
|
||||||
|
|
||||||
|
@return
|
||||||
|
@retval fixed object name.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const char* fix_identifier_with_newline(char* object_name)
|
||||||
|
{
|
||||||
|
static char buff[COMMENT_LENGTH]= {0};
|
||||||
|
char *ptr= buff;
|
||||||
|
memset(buff, 0, 255);
|
||||||
|
while(*object_name)
|
||||||
|
{
|
||||||
|
*ptr++ = *object_name;
|
||||||
|
if (*object_name == '\n')
|
||||||
|
ptr= strmov(ptr, "-- ");
|
||||||
|
object_name++;
|
||||||
|
}
|
||||||
|
return buff;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
create_delimiter
|
create_delimiter
|
||||||
@ -2049,7 +2074,8 @@ static uint dump_events_for_db(char *db)
|
|||||||
|
|
||||||
/* nice comments */
|
/* nice comments */
|
||||||
print_comment(sql_file, 0,
|
print_comment(sql_file, 0,
|
||||||
"\n--\n-- Dumping events for database '%s'\n--\n", db);
|
"\n--\n-- Dumping events for database '%s'\n--\n",
|
||||||
|
fix_identifier_with_newline(db));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
not using "mysql_query_with_error_report" because we may have not
|
not using "mysql_query_with_error_report" because we may have not
|
||||||
@ -2266,7 +2292,8 @@ static uint dump_routines_for_db(char *db)
|
|||||||
|
|
||||||
/* nice comments */
|
/* nice comments */
|
||||||
print_comment(sql_file, 0,
|
print_comment(sql_file, 0,
|
||||||
"\n--\n-- Dumping routines for database '%s'\n--\n", db);
|
"\n--\n-- Dumping routines for database '%s'\n--\n",
|
||||||
|
fix_identifier_with_newline(db));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
not using "mysql_query_with_error_report" because we may have not
|
not using "mysql_query_with_error_report" because we may have not
|
||||||
@ -2325,7 +2352,7 @@ static uint dump_routines_for_db(char *db)
|
|||||||
query_buff);
|
query_buff);
|
||||||
print_comment(sql_file, 1,
|
print_comment(sql_file, 1,
|
||||||
"-- does %s have permissions on mysql.proc?\n\n",
|
"-- does %s have permissions on mysql.proc?\n\n",
|
||||||
current_user);
|
fix_identifier_with_newline(current_user));
|
||||||
maybe_die(EX_MYSQLERR,"%s has insufficent privileges to %s!", current_user, query_buff);
|
maybe_die(EX_MYSQLERR,"%s has insufficent privileges to %s!", current_user, query_buff);
|
||||||
}
|
}
|
||||||
else if (strlen(row[2]))
|
else if (strlen(row[2]))
|
||||||
@ -2539,11 +2566,11 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
|||||||
if (strcmp (table_type, "VIEW") == 0) /* view */
|
if (strcmp (table_type, "VIEW") == 0) /* view */
|
||||||
print_comment(sql_file, 0,
|
print_comment(sql_file, 0,
|
||||||
"\n--\n-- Temporary table structure for view %s\n--\n\n",
|
"\n--\n-- Temporary table structure for view %s\n--\n\n",
|
||||||
result_table);
|
fix_identifier_with_newline(result_table));
|
||||||
else
|
else
|
||||||
print_comment(sql_file, 0,
|
print_comment(sql_file, 0,
|
||||||
"\n--\n-- Table structure for table %s\n--\n\n",
|
"\n--\n-- Table structure for table %s\n--\n\n",
|
||||||
result_table);
|
fix_identifier_with_newline(result_table));
|
||||||
|
|
||||||
if (opt_drop)
|
if (opt_drop)
|
||||||
{
|
{
|
||||||
@ -2785,7 +2812,7 @@ static uint get_table_structure(char *table, char *db, char *table_type,
|
|||||||
|
|
||||||
print_comment(sql_file, 0,
|
print_comment(sql_file, 0,
|
||||||
"\n--\n-- Table structure for table %s\n--\n\n",
|
"\n--\n-- Table structure for table %s\n--\n\n",
|
||||||
result_table);
|
fix_identifier_with_newline(result_table));
|
||||||
if (opt_drop)
|
if (opt_drop)
|
||||||
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table);
|
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table);
|
||||||
if (!opt_xml)
|
if (!opt_xml)
|
||||||
@ -3490,21 +3517,23 @@ static void dump_table(char *table, char *db)
|
|||||||
{
|
{
|
||||||
print_comment(md_result_file, 0,
|
print_comment(md_result_file, 0,
|
||||||
"\n--\n-- Dumping data for table %s\n--\n",
|
"\n--\n-- Dumping data for table %s\n--\n",
|
||||||
result_table);
|
fix_identifier_with_newline(result_table));
|
||||||
|
|
||||||
dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM ");
|
dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM ");
|
||||||
dynstr_append_checked(&query_string, result_table);
|
dynstr_append_checked(&query_string, result_table);
|
||||||
|
|
||||||
if (where)
|
if (where)
|
||||||
{
|
{
|
||||||
print_comment(md_result_file, 0, "-- WHERE: %s\n", where);
|
print_comment(md_result_file, 0, "-- WHERE: %s\n",
|
||||||
|
fix_identifier_with_newline(where));
|
||||||
|
|
||||||
dynstr_append_checked(&query_string, " WHERE ");
|
dynstr_append_checked(&query_string, " WHERE ");
|
||||||
dynstr_append_checked(&query_string, where);
|
dynstr_append_checked(&query_string, where);
|
||||||
}
|
}
|
||||||
if (order_by)
|
if (order_by)
|
||||||
{
|
{
|
||||||
print_comment(md_result_file, 0, "-- ORDER BY: %s\n", order_by);
|
print_comment(md_result_file, 0, "-- ORDER BY: %s\n",
|
||||||
|
fix_identifier_with_newline(order_by));
|
||||||
|
|
||||||
dynstr_append_checked(&query_string, " ORDER BY ");
|
dynstr_append_checked(&query_string, " ORDER BY ");
|
||||||
dynstr_append_checked(&query_string, order_by);
|
dynstr_append_checked(&query_string, order_by);
|
||||||
@ -4275,7 +4304,8 @@ static int init_dumping(char *database, int init_func(char*))
|
|||||||
char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
|
char *qdatabase= quote_name(database,quoted_database_buf,opt_quoted);
|
||||||
|
|
||||||
print_comment(md_result_file, 0,
|
print_comment(md_result_file, 0,
|
||||||
"\n--\n-- Current Database: %s\n--\n", qdatabase);
|
"\n--\n-- Current Database: %s\n--\n",
|
||||||
|
fix_identifier_with_newline(qdatabase));
|
||||||
|
|
||||||
/* Call the view or table specific function */
|
/* Call the view or table specific function */
|
||||||
init_func(qdatabase);
|
init_func(qdatabase);
|
||||||
@ -5281,7 +5311,7 @@ static my_bool get_view_structure(char *table, char* db)
|
|||||||
|
|
||||||
print_comment(sql_file, 0,
|
print_comment(sql_file, 0,
|
||||||
"\n--\n-- Final view structure for view %s\n--\n\n",
|
"\n--\n-- Final view structure for view %s\n--\n\n",
|
||||||
result_table);
|
fix_identifier_with_newline(result_table));
|
||||||
|
|
||||||
/* Table might not exist if this view was dumped with --tab. */
|
/* Table might not exist if this view was dumped with --tab. */
|
||||||
fprintf(sql_file, "/*!50001 DROP TABLE IF EXISTS %s*/;\n", opt_quoted_table);
|
fprintf(sql_file, "/*!50001 DROP TABLE IF EXISTS %s*/;\n", opt_quoted_table);
|
||||||
|
@ -5283,3 +5283,66 @@ a
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
DROP DATABASE db_20772273;
|
DROP DATABASE db_20772273;
|
||||||
|
#
|
||||||
|
# Bug #25717383: MYSQLDUMP MAY EXECUTE ANY ARBITRARY QUERY
|
||||||
|
#
|
||||||
|
CREATE DATABASE bug25717383;
|
||||||
|
use bug25717383;
|
||||||
|
CREATE TABLE `tab
|
||||||
|
one` (a int);
|
||||||
|
CREATE VIEW `view
|
||||||
|
one` as SELECT * FROM `tab
|
||||||
|
one`;
|
||||||
|
CREATE PROCEDURE `proc
|
||||||
|
one`() SELECT * from `tab
|
||||||
|
one`;
|
||||||
|
CREATE TEMPORARY TABLE `temp
|
||||||
|
one` (id INT);
|
||||||
|
CREATE TRIGGER `trig
|
||||||
|
one` BEFORE INSERT ON `tab
|
||||||
|
one` FOR EACH ROW SET NEW.a = 1;
|
||||||
|
CREATE EVENT `event
|
||||||
|
one` ON SCHEDULE AT '2030-01-01 00:00:00' DO SET @a=5;
|
||||||
|
SHOW TABLES FROM bug25717383;
|
||||||
|
Tables_in_bug25717383
|
||||||
|
tab
|
||||||
|
one
|
||||||
|
view
|
||||||
|
one
|
||||||
|
SHOW TRIGGERS FROM bug25717383;
|
||||||
|
Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
|
||||||
|
trig
|
||||||
|
one INSERT tab
|
||||||
|
one SET NEW.a = 1 BEFORE NULL root@localhost utf8 utf8_general_ci latin1_swedish_ci
|
||||||
|
SHOW EVENTS FROM bug25717383;
|
||||||
|
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
|
||||||
|
bug25717383 event
|
||||||
|
one root@localhost SYSTEM ONE TIME # NULL NULL NULL NULL ENABLED 1 utf8 utf8_general_ci latin1_swedish_ci
|
||||||
|
SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES
|
||||||
|
WHERE ROUTINE_SCHEMA='bug25717383' AND ROUTINE_TYPE= 'PROCEDURE'
|
||||||
|
ORDER BY ROUTINE_NAME;
|
||||||
|
ROUTINE_NAME
|
||||||
|
proc
|
||||||
|
one
|
||||||
|
SHOW TABLES FROM bug25717383;
|
||||||
|
Tables_in_bug25717383
|
||||||
|
tab
|
||||||
|
one
|
||||||
|
view
|
||||||
|
one
|
||||||
|
SHOW TRIGGERS FROM bug25717383;
|
||||||
|
Trigger Event Table Statement Timing Created sql_mode Definer character_set_client collation_connection Database Collation
|
||||||
|
trig
|
||||||
|
one INSERT tab
|
||||||
|
one SET NEW.a = 1 BEFORE NULL root@localhost utf8 utf8_general_ci latin1_swedish_ci
|
||||||
|
SHOW EVENTS FROM bug25717383;
|
||||||
|
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
|
||||||
|
bug25717383 event
|
||||||
|
one root@localhost SYSTEM ONE TIME # NULL NULL NULL NULL ENABLED 1 utf8 utf8_general_ci latin1_swedish_ci
|
||||||
|
SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES
|
||||||
|
WHERE ROUTINE_SCHEMA='bug25717383' AND ROUTINE_TYPE= 'PROCEDURE'
|
||||||
|
ORDER BY ROUTINE_NAME;
|
||||||
|
ROUTINE_NAME
|
||||||
|
proc
|
||||||
|
one
|
||||||
|
DROP DATABASE bug25717383;
|
||||||
|
@ -2425,3 +2425,53 @@ SELECT * FROM t2;
|
|||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
DROP TABLE t2;
|
DROP TABLE t2;
|
||||||
DROP DATABASE db_20772273;
|
DROP DATABASE db_20772273;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # Bug #25717383: MYSQLDUMP MAY EXECUTE ANY ARBITRARY QUERY
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
|
||||||
|
CREATE DATABASE bug25717383;
|
||||||
|
use bug25717383;
|
||||||
|
|
||||||
|
CREATE TABLE `tab
|
||||||
|
one` (a int);
|
||||||
|
CREATE VIEW `view
|
||||||
|
one` as SELECT * FROM `tab
|
||||||
|
one`;
|
||||||
|
|
||||||
|
CREATE PROCEDURE `proc
|
||||||
|
one`() SELECT * from `tab
|
||||||
|
one`;
|
||||||
|
|
||||||
|
CREATE TEMPORARY TABLE `temp
|
||||||
|
one` (id INT);
|
||||||
|
|
||||||
|
CREATE TRIGGER `trig
|
||||||
|
one` BEFORE INSERT ON `tab
|
||||||
|
one` FOR EACH ROW SET NEW.a = 1;
|
||||||
|
|
||||||
|
CREATE EVENT `event
|
||||||
|
one` ON SCHEDULE AT '2030-01-01 00:00:00' DO SET @a=5;
|
||||||
|
|
||||||
|
SHOW TABLES FROM bug25717383;
|
||||||
|
SHOW TRIGGERS FROM bug25717383;
|
||||||
|
--replace_column 6 #
|
||||||
|
SHOW EVENTS FROM bug25717383;
|
||||||
|
|
||||||
|
SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES
|
||||||
|
WHERE ROUTINE_SCHEMA='bug25717383' AND ROUTINE_TYPE= 'PROCEDURE'
|
||||||
|
ORDER BY ROUTINE_NAME;
|
||||||
|
|
||||||
|
--exec $MYSQL_DUMP --triggers --events --routines --add-drop-database --databases bug25717383 > $MYSQLTEST_VARDIR/tmp/bug25717383.sql
|
||||||
|
|
||||||
|
SHOW TABLES FROM bug25717383;
|
||||||
|
SHOW TRIGGERS FROM bug25717383;
|
||||||
|
--replace_column 6 #
|
||||||
|
SHOW EVENTS FROM bug25717383;
|
||||||
|
|
||||||
|
SELECT ROUTINE_NAME FROM INFORMATION_SCHEMA.ROUTINES
|
||||||
|
WHERE ROUTINE_SCHEMA='bug25717383' AND ROUTINE_TYPE= 'PROCEDURE'
|
||||||
|
ORDER BY ROUTINE_NAME;
|
||||||
|
|
||||||
|
DROP DATABASE bug25717383;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user