diff options
author | Andrei Elkin <aelkin@mysql.com> | 2009-03-26 11:28:07 +0200 |
---|---|---|
committer | Andrei Elkin <aelkin@mysql.com> | 2009-03-26 11:28:07 +0200 |
commit | fb8ac41a3b922a3bde234ee11c5ac808395afa34 (patch) | |
tree | 530d5f328544ed43547df6ebb847aaab7a46b14e | |
parent | 27cf68795e42b088e5b20551b60dce02a0b52e1d (diff) | |
parent | aca1a83fedd916492c97f77557d27c79ae54da43 (diff) | |
download | mariadb-git-fb8ac41a3b922a3bde234ee11c5ac808395afa34.tar.gz |
merge from 5.1-pe-stage to a local tree
-rw-r--r-- | mysql-test/extra/binlog_tests/binlog.test | 40 | ||||
-rw-r--r-- | mysql-test/suite/binlog/r/binlog_row_binlog.result | 32 | ||||
-rw-r--r-- | mysql-test/suite/binlog/r/binlog_stm_binlog.result | 32 | ||||
-rw-r--r-- | mysql-test/suite/rpl/r/rpl_temporary.result | 10 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_temporary.test | 38 | ||||
-rw-r--r-- | sql/sp_head.cc | 5 | ||||
-rw-r--r-- | sql/sql_class.cc | 9 | ||||
-rw-r--r-- | sql/sql_class.h | 4 | ||||
-rw-r--r-- | sql/sql_parse.cc | 57 |
9 files changed, 226 insertions, 1 deletions
diff --git a/mysql-test/extra/binlog_tests/binlog.test b/mysql-test/extra/binlog_tests/binlog.test index 98bd116ba29..d72dc693cee 100644 --- a/mysql-test/extra/binlog_tests/binlog.test +++ b/mysql-test/extra/binlog_tests/binlog.test @@ -164,6 +164,46 @@ DROP TABLE t1; DROP DATABASE bug39182; USE test; +# +# Bug#35383: binlog playback and replication breaks due to +# name_const substitution +# +DELIMITER //; +CREATE PROCEDURE p1(IN v1 INT) +BEGIN + CREATE TABLE t1 SELECT v1; + DROP TABLE t1; +END// +CREATE PROCEDURE p2() +BEGIN + DECLARE v1 INT; + CREATE TABLE t1 SELECT v1+1; + DROP TABLE t1; +END// +CREATE PROCEDURE p3(IN v1 INT) +BEGIN + CREATE TABLE t1 SELECT 1 FROM DUAL WHERE v1!=0; + DROP TABLE t1; +END// +CREATE PROCEDURE p4(IN v1 INT) +BEGIN + DECLARE v2 INT; + CREATE TABLE t1 SELECT 1, v1, v2; + DROP TABLE t1; + CREATE TABLE t1 SELECT 1, v1+1, v2; + DROP TABLE t1; +END// +DELIMITER ;// + +CALL p1(1); +CALL p2(); +CALL p3(0); +CALL p4(0); +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP PROCEDURE p3; +DROP PROCEDURE p4; + --echo End of 5.0 tests # Test of a too big SET INSERT_ID: see if the truncated value goes diff --git a/mysql-test/suite/binlog/r/binlog_row_binlog.result b/mysql-test/suite/binlog/r/binlog_row_binlog.result index 1a56e048b27..25cb7a4726f 100644 --- a/mysql-test/suite/binlog/r/binlog_row_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result @@ -1137,6 +1137,38 @@ DROP PROCEDURE p1; DROP TABLE t1; DROP DATABASE bug39182; USE test; +CREATE PROCEDURE p1(IN v1 INT) +BEGIN +CREATE TABLE t1 SELECT v1; +DROP TABLE t1; +END// +CREATE PROCEDURE p2() +BEGIN +DECLARE v1 INT; +CREATE TABLE t1 SELECT v1+1; +DROP TABLE t1; +END// +CREATE PROCEDURE p3(IN v1 INT) +BEGIN +CREATE TABLE t1 SELECT 1 FROM DUAL WHERE v1!=0; +DROP TABLE t1; +END// +CREATE PROCEDURE p4(IN v1 INT) +BEGIN +DECLARE v2 INT; +CREATE TABLE t1 SELECT 1, v1, v2; +DROP TABLE t1; +CREATE TABLE t1 SELECT 1, v1+1, v2; +DROP TABLE t1; +END// +CALL p1(1); +CALL p2(); +CALL p3(0); +CALL p4(0); +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP PROCEDURE p3; +DROP PROCEDURE p4; End of 5.0 tests reset master; create table t1 (id tinyint auto_increment primary key); diff --git a/mysql-test/suite/binlog/r/binlog_stm_binlog.result b/mysql-test/suite/binlog/r/binlog_stm_binlog.result index aadbf950b21..efdeb30a2af 100644 --- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result +++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result @@ -644,6 +644,38 @@ DROP PROCEDURE p1; DROP TABLE t1; DROP DATABASE bug39182; USE test; +CREATE PROCEDURE p1(IN v1 INT) +BEGIN +CREATE TABLE t1 SELECT v1; +DROP TABLE t1; +END// +CREATE PROCEDURE p2() +BEGIN +DECLARE v1 INT; +CREATE TABLE t1 SELECT v1+1; +DROP TABLE t1; +END// +CREATE PROCEDURE p3(IN v1 INT) +BEGIN +CREATE TABLE t1 SELECT 1 FROM DUAL WHERE v1!=0; +DROP TABLE t1; +END// +CREATE PROCEDURE p4(IN v1 INT) +BEGIN +DECLARE v2 INT; +CREATE TABLE t1 SELECT 1, v1, v2; +DROP TABLE t1; +CREATE TABLE t1 SELECT 1, v1+1, v2; +DROP TABLE t1; +END// +CALL p1(1); +CALL p2(); +CALL p3(0); +CALL p4(0); +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP PROCEDURE p3; +DROP PROCEDURE p4; End of 5.0 tests reset master; create table t1 (id tinyint auto_increment primary key); diff --git a/mysql-test/suite/rpl/r/rpl_temporary.result b/mysql-test/suite/rpl/r/rpl_temporary.result index 568d5368adb..c3b228e6089 100644 --- a/mysql-test/suite/rpl/r/rpl_temporary.result +++ b/mysql-test/suite/rpl/r/rpl_temporary.result @@ -108,3 +108,13 @@ select * from t1; a 1 drop table t1; +Bug#43748 +make a non-privileged user on slave. +FLUSH PRIVILEGES; +GRANT USAGE ON *.* TO user43748@127.0.0.1 IDENTIFIED BY 'meow'; +try to KILL system-thread as non-privileged user. +KILL `select id from information_schema.processlist where command='Binlog Dump'`; +ERROR HY000: You are not owner of thread `select id from information_schema.processlist where command='Binlog Dump'` +throw out test-user on slave. +DROP USER user43748@127.0.0.1; +done. back to master. diff --git a/mysql-test/suite/rpl/t/rpl_temporary.test b/mysql-test/suite/rpl/t/rpl_temporary.test index 0bf3ecf97a2..a236bcf3b7b 100644 --- a/mysql-test/suite/rpl/t/rpl_temporary.test +++ b/mysql-test/suite/rpl/t/rpl_temporary.test @@ -222,4 +222,42 @@ drop table t1; # Delete the anonymous users source include/delete_anonymous_users.inc; + + +# +# Bug#43748: crash when non-super user tries to kill the replication threads +# + +--echo Bug#43748 + +connection slave; + +--echo make a non-privileged user on slave. + +FLUSH PRIVILEGES; +GRANT USAGE ON *.* TO user43748@127.0.0.1 IDENTIFIED BY 'meow'; + +let $id = `SELECT id FROM information_schema.processlist WHERE user='system user' LIMIT 1`; + +connect (cont43748,127.0.0.1,user43748,meow,test,$SLAVE_MYPORT,); +connection cont43748; + +--echo try to KILL system-thread as non-privileged user. + +--replace_result $id "`select id from information_schema.processlist where command='Binlog Dump'`" +--error ER_KILL_DENIED_ERROR +eval KILL $id; + +disconnect cont43748; + +connection slave; + +--echo throw out test-user on slave. +DROP USER user43748@127.0.0.1; + +connection master; +--echo done. back to master. + + + # End of tests diff --git a/sql/sp_head.cc b/sql/sp_head.cc index ef6cb556f4c..fcf51aac1b5 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -956,6 +956,8 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str) qbuf.length(0); cur= query_str->str; prev_pos= res= 0; + thd->query_name_consts= 0; + for (Item_splocal **splocal= sp_vars_uses.front(); splocal < sp_vars_uses.back(); splocal++) { @@ -989,6 +991,8 @@ subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str) res|= qbuf.append(')'); if (res) break; + + thd->query_name_consts++; } res|= qbuf.append(cur + prev_pos, query_str->length - prev_pos); if (res) @@ -2853,6 +2857,7 @@ sp_instr_stmt::execute(THD *thd, uint *nextp) *nextp= m_ip+1; thd->query= query; thd->query_length= query_length; + thd->query_name_consts= 0; if (!thd->is_error()) thd->main_da.reset_diagnostics_area(); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 945a0484068..7f15508caa1 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -599,6 +599,7 @@ THD::THD() one_shot_set= 0; file_id = 0; query_id= 0; + query_name_consts= 0; warn_id= 0; db_charset= global_system_variables.collation_database; bzero(ha_data, sizeof(ha_data)); @@ -2805,6 +2806,14 @@ Security_context::restore_security_context(THD *thd, } #endif + +bool Security_context::user_matches(Security_context *them) +{ + return ((user != NULL) && (them->user != NULL) && + !strcmp(user, them->user)); +} + + /**************************************************************************** Handling of open and locked tables states. diff --git a/sql/sql_class.h b/sql/sql_class.h index 304937101c4..ce4524fb982 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -813,6 +813,7 @@ public: void restore_security_context(THD *thd, Security_context *backup); #endif + bool user_matches(Security_context *); }; @@ -1774,6 +1775,9 @@ public: sp_cache *sp_proc_cache; sp_cache *sp_func_cache; + /** number of name_const() substitutions, see sp_head.cc:subst_spvars() */ + uint query_name_consts; + /* If we do a purge of binary logs, log index info of the threads that are currently reading it needs to be adjusted. To do that diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 94725b1b53f..2974dff9ea9 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2558,6 +2558,43 @@ mysql_execute_command(THD *thd) { select_result *result; + /* + If: + a) we inside an SP and there was NAME_CONST substitution, + b) binlogging is on (STMT mode), + c) we log the SP as separate statements + raise a warning, as it may cause problems + (see 'NAME_CONST issues' in 'Binary Logging of Stored Programs') + */ + if (thd->query_name_consts && + mysql_bin_log.is_open() && + thd->variables.binlog_format == BINLOG_FORMAT_STMT && + !mysql_bin_log.is_query_in_union(thd, thd->query_id)) + { + List_iterator_fast<Item> it(select_lex->item_list); + Item *item; + uint splocal_refs= 0; + /* Count SP local vars in the top-level SELECT list */ + while ((item= it++)) + { + if (item->is_splocal()) + splocal_refs++; + } + /* + If it differs from number of NAME_CONST substitution applied, + we may have a SOME_FUNC(NAME_CONST()) in the SELECT list, + that may cause a problem with binary log (see BUG#35383), + raise a warning. + */ + if (splocal_refs != thd->query_name_consts) + push_warning(thd, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_UNKNOWN_ERROR, +"Invoked routine ran a statement that may cause problems with " +"binary log, see 'NAME_CONST issues' in 'Binary Logging of Stored Programs' " +"section of the manual."); + } + select_lex->options|= SELECT_NO_UNLOCK; unit->set_limit(select_lex); @@ -6890,8 +6927,26 @@ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query) VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (tmp) { + + /* + If we're SUPER, we can KILL anything, including system-threads. + No further checks. + + KILLer: thd->security_ctx->user could in theory be NULL while + we're still in "unauthenticated" state. This is a theoretical + case (the code suggests this could happen, so we play it safe). + + KILLee: tmp->security_ctx->user will be NULL for system threads. + We need to check so Jane Random User doesn't crash the server + when trying to kill a) system threads or b) unauthenticated users' + threads (Bug#43748). + + If user of both killer and killee are non-NULL, proceed with + slayage if both are string-equal. + */ + if ((thd->security_ctx->master_access & SUPER_ACL) || - !strcmp(thd->security_ctx->user, tmp->security_ctx->user)) + thd->security_ctx->user_matches(tmp->security_ctx)) { tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION); error=0; |