List:Commits« Previous MessageNext Message »
From:Andrei Elkin Date:March 26 2009 9:28am
Subject:bzr commit into mysql-5.1-bugteam branch (aelkin:2843)
View as plain text  
#At file:///home/andrei/MySQL/BZR/mysql-5.1-pe-stage/ based on revid:aelkin@stripped

 2843 Andrei Elkin	2009-03-26 [merge]
      merge from 5.1-pe-stage to a local tree
modified:
  mysql-test/extra/binlog_tests/binlog.test
  mysql-test/suite/binlog/r/binlog_row_binlog.result
  mysql-test/suite/binlog/r/binlog_stm_binlog.result
  mysql-test/suite/rpl/r/rpl_temporary.result
  mysql-test/suite/rpl/t/rpl_temporary.test
  sql/sp_head.cc
  sql/sql_class.cc
  sql/sql_class.h
  sql/sql_parse.cc

=== modified file 'mysql-test/extra/binlog_tests/binlog.test'
--- a/mysql-test/extra/binlog_tests/binlog.test	2008-10-02 05:56:07 +0000
+++ b/mysql-test/extra/binlog_tests/binlog.test	2009-03-25 19:41:16 +0000
@@ -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

=== modified file 'mysql-test/suite/binlog/r/binlog_row_binlog.result'
--- a/mysql-test/suite/binlog/r/binlog_row_binlog.result	2008-10-02 05:56:07 +0000
+++ b/mysql-test/suite/binlog/r/binlog_row_binlog.result	2009-03-25 19:41:16 +0000
@@ -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);

=== modified file 'mysql-test/suite/binlog/r/binlog_stm_binlog.result'
--- a/mysql-test/suite/binlog/r/binlog_stm_binlog.result	2008-10-02 05:56:07 +0000
+++ b/mysql-test/suite/binlog/r/binlog_stm_binlog.result	2009-03-25 19:41:16 +0000
@@ -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);

=== modified file 'mysql-test/suite/rpl/r/rpl_temporary.result'
--- a/mysql-test/suite/rpl/r/rpl_temporary.result	2008-10-23 19:27:09 +0000
+++ b/mysql-test/suite/rpl/r/rpl_temporary.result	2009-03-25 16:42:34 +0000
@@ -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@stripped 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@stripped;
+done. back to master.

=== modified file 'mysql-test/suite/rpl/t/rpl_temporary.test'
--- a/mysql-test/suite/rpl/t/rpl_temporary.test	2008-10-23 19:27:09 +0000
+++ b/mysql-test/suite/rpl/t/rpl_temporary.test	2009-03-25 16:42:34 +0000
@@ -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@stripped 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@stripped;
+
+connection master;
+--echo done. back to master.
+
+
+
 # End of tests

=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc	2009-02-13 16:41:47 +0000
+++ b/sql/sp_head.cc	2009-03-25 19:41:16 +0000
@@ -956,6 +956,8 @@ subst_spvars(THD *thd, sp_instr *instr, 
   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, 
     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 *n
       *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();

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2009-03-24 13:58:52 +0000
+++ b/sql/sql_class.cc	2009-03-25 19:41:16 +0000
@@ -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_conte
 }
 #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.
 

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2009-03-19 14:43:01 +0000
+++ b/sql/sql_class.h	2009-03-25 19:41:16 +0000
@@ -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

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2009-03-24 13:58:52 +0000
+++ b/sql/sql_parse.cc	2009-03-25 19:41:16 +0000
@@ -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,
   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;

Thread
bzr commit into mysql-5.1-bugteam branch (aelkin:2843)Andrei Elkin26 Mar