From: Nuno Carvalho Date: March 26 2012 10:32pm Subject: bzr push into mysql-trunk branch (nuno.carvalho:3861 to 3862) Bug#13799555 List-Archive: http://lists.mysql.com/commits/143316 X-Bug: 13799555 Message-Id: <201203262232.q2QMWlqL016826@acsmt356.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3862 Nuno Carvalho 2012-03-26 Bug#13799555: ROWS_QUERY_LOG_EVENTS DOES NOT ESCAPE MULTI-LINE QUERIES PROPERLY Revert previous patch due to solaris build problems. modified: mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test sql/log_event.cc 3861 Nuno Carvalho 2012-03-26 Bug#13799555: ROWS_QUERY_LOG_EVENTS DOES NOT ESCAPE MULTI-LINE QUERIES PROPERLY When binlog_rows_query_log_events = 1 and a statement is written to the binary log in row format, the server generates a log event containing the original query text. If mysqlbinlog is given the option --verbose --verbose the original statement is printed. To prevent the statement from being executed, it is prefixed by '#'. However, this is not enough for multi-line statements: only the first line of the query will be commented out. If a malicious user knows that the binary log will be processed using mysqlbinlog --verbose --verbose, then the user can execute arbitrary statements on the server. Prefix every line of a multi-line query with '#' to prevent the statement from being executed when binary log will be processed using 'mysqlbinlog --verbose --verbose'. modified: mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test sql/log_event.cc === modified file 'mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result' --- a/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result 2012-03-26 21:29:37 +0000 +++ b/mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_verbose.result 2012-03-26 22:32:02 +0000 @@ -159,9 +159,3 @@ stmt ### WHERE ### @1=2 drop table raw_binlog_rows; -SET @@SESSION.BINLOG_ROWS_QUERY_LOG_EVENTS = 1; -CREATE TABLE t1 (a VARCHAR(50)); -INSERT INTO t1 VALUES (" - GRANT ALL ON *.* TO 'batman'/*!*/; - ")| -DROP TABLE t1; === modified file 'mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test' --- a/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test 2012-03-26 21:29:37 +0000 +++ b/mysql-test/suite/binlog/t/binlog_row_mysqlbinlog_verbose.test 2012-03-26 22:32:02 +0000 @@ -32,6 +32,9 @@ # tool and the output is checked. # ######################################################## + +# We require binlog_format_row as we're independent of binlog format +# and there's no point running the same test 3 times -- source include/have_binlog_format_row.inc --disable_query_log @@ -81,63 +84,3 @@ create table raw_binlog_rows (txt varcha # Output --verbose lines, with extra Windows CR's trimmed select replace(txt,'\r', '') as stmt from raw_binlog_rows where txt like '###%'; drop table raw_binlog_rows; - - -####################################################################### -# BUG#13799555: ROWS_QUERY_LOG_EVENTS DOES NOT ESCAPE MULTI-LINE QUERIES PROPERLY -# -# Check that when mysqlbinlog is given the option --verbose --verbose, -# the multi-line original statement are properly escaped to prevent from -# being executed. -SET @@SESSION.BINLOG_ROWS_QUERY_LOG_EVENTS = 1; -CREATE TABLE t1 (a VARCHAR(50)); ---let $binlog_start_position= query_get_value("SHOW MASTER STATUS", Position, 1) - ---delimiter | -INSERT INTO t1 VALUES (" - GRANT ALL ON *.* TO 'batman'/*!*/; - ")| ---delimiter ; - ---let $binlog_stop_position= query_get_value("SHOW MASTER STATUS", Position, 1) ---let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) ---let $datadir= `SELECT @@datadir` - ---let $_prefix= `SELECT UUID()` ---let $TMP_FILE= $MYSQLTEST_VARDIR/tmp/$_prefix.tmp ---exec $MYSQL_BINLOG --force-if-open --verbose --verbose --start-position=$binlog_start_position --stop-position=$binlog_stop_position $datadir/$binlog_file > $TMP_FILE - ---let TMP_FILE= $TMP_FILE ---perl END_OF_FILE -my $tmp_file= $ENV{'TMP_FILE'}; - -my $escaped_query = < }; -close(FILE) or die("Unable to close file."); - -$match= index($contents, $escaped_query) > -1; -if (!$match) -{ - print "\n====================================================\n"; - print "ESCAPED STRING DID NOT MATCH:\n"; - print "====================================================\n"; - print "$escaped_query"; - print "====================================================\n"; - - print "\n====================================================\n"; - print "BINLOG CONTENTS\n"; - print "====================================================\n"; - print "$contents"; - print "====================================================\n"; -} -END_OF_FILE - -# Clean up -DROP TABLE t1; ---remove_file $TMP_FILE === modified file 'sql/log_event.cc' --- a/sql/log_event.cc 2012-03-26 21:29:37 +0000 +++ b/sql/log_event.cc 2012-03-26 22:32:02 +0000 @@ -11807,21 +11807,9 @@ Rows_query_log_event::print(FILE *file, { IO_CACHE *const head= &print_event_info->head_cache; IO_CACHE *const body= &print_event_info->body_cache; - uint m_rows_query_len= strlen(m_rows_query); - char rows_query_copy[m_rows_query_len + 1]; - char *token= NULL, *saveptr= NULL; - print_header(head, print_event_info, FALSE); my_b_printf(head, "\tRows_query\n"); - /* - Prefix every line of a multi-line query with '#' to prevent the - statement from being executed when binary log will be processed - using 'mysqlbinlog --verbose --verbose'. - */ - strmake(rows_query_copy, m_rows_query, m_rows_query_len); - for (token= strtok_r(rows_query_copy, "\n", &saveptr); token; - token= strtok_r(NULL, "\n", &saveptr)) - my_b_printf(head, "# %s\n", token); + my_b_printf(head, "# %s\n", m_rows_query); print_base64(body, print_event_info, true); } } No bundle (reason: useless for push emails).