MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:konstantin Date:April 7 2006 7:51pm
Subject:bk commit into 4.1 tree (konstantin:1.2504)
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of kostja. When kostja does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet
  1.2504 06/04/07 23:50:45 konstantin@stripped +4 -0
  Merge bk-internal.mysql.com:/home/bk/mysql-4.1
  into  mysql.com:/opt/local/work/mysql-4.1-16365

  mysql-test/t/ps.test
    1.50 06/04/07 23:50:37 konstantin@stripped +18 -18
    Manual merge

  mysql-test/r/ps.result
    1.49 06/04/07 23:50:37 konstantin@stripped +20 -20
    Manual merge

  sql/sql_class.h
    1.285 06/04/07 23:48:18 konstantin@stripped +0 -0
    Auto merged

  sql/mysql_priv.h
    1.375 06/04/07 23:48:18 konstantin@stripped +0 -0
    Auto merged

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	konstantin
# Host:	dragonfly.local
# Root:	/opt/local/work/mysql-4.1-16365/RESYNC

--- 1.374/sql/mysql_priv.h	2006-03-29 23:20:58 +04:00
+++ 1.375/sql/mysql_priv.h	2006-04-07 23:48:18 +04:00
@@ -918,6 +918,7 @@
 extern ulong max_connections,max_connect_errors, connect_timeout;
 extern ulong slave_net_timeout, slave_trans_retries;
 extern ulong max_user_connections;
+extern ulong max_prepared_stmt_count, prepared_stmt_count;
 extern ulong long_query_count, what_to_log,flush_time;
 extern ulong query_buff_size, thread_stack,thread_stack_min;
 extern ulong binlog_cache_size, max_binlog_cache_size, open_files_limit;
@@ -961,7 +962,8 @@
        LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator,
        LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone,
        LOCK_slave_list, LOCK_active_mi, LOCK_manager,
-       LOCK_global_system_variables, LOCK_user_conn;
+       LOCK_global_system_variables, LOCK_user_conn,
+       LOCK_prepared_stmt_count;
 #ifdef HAVE_OPENSSL
 extern pthread_mutex_t LOCK_des_key_file;
 #endif

--- 1.284/sql/sql_class.h	2006-03-29 23:18:44 +04:00
+++ 1.285/sql/sql_class.h	2006-04-07 23:48:18 +04:00
@@ -620,7 +620,7 @@
 public:
   Statement_map();
 
-  int insert(Statement *statement);
+  int insert(THD *thd, Statement *statement);
 
   Statement *find_by_name(LEX_STRING *name)
   {
@@ -642,29 +642,10 @@
     }
     return last_found_statement;
   }
-  void erase(Statement *statement)
-  {
-    if (statement == last_found_statement)
-      last_found_statement= 0;
-    if (statement->name.str)
-    {
-      hash_delete(&names_hash, (byte *) statement);  
-    }
-    hash_delete(&st_hash, (byte *) statement);
-  }
+  void erase(Statement *statement);
   /* Erase all statements (calls Statement destructor) */
-  void reset()
-  {
-    my_hash_reset(&names_hash);
-    my_hash_reset(&st_hash);
-    last_found_statement= 0;
-  }
-
-  ~Statement_map()
-  {
-    hash_free(&names_hash);
-    hash_free(&st_hash);
-  }
+  void reset();
+  ~Statement_map();
 private:
   HASH st_hash;
   HASH names_hash;
@@ -932,6 +913,7 @@
   {
     my_bool my_bool_value;
     long    long_value;
+    ulong   ulong_value;
   } sys_var_tmp;
 
   THD();

--- 1.48/mysql-test/r/ps.result	2006-04-07 22:26:15 +04:00
+++ 1.49/mysql-test/r/ps.result	2006-04-07 23:50:37 +04:00
@@ -107,6 +107,9 @@
 prepare stmt1 from @fvar;
 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '123.4567' at line 1
 drop table t1,t2;
+deallocate prepare stmt3;
+deallocate prepare stmt4;
+deallocate prepare stmt5;
 PREPARE stmt1 FROM "select _utf8 'A' collate utf8_bin = ?";
 set @var='A';
 EXECUTE stmt1 USING @var;
@@ -252,6 +255,7 @@
 1234
 1234
 set names default;
 create table t1 (a varchar(10)) charset=utf8;
 insert into t1 (a) values ('yahoo');
@@ -767,3 +771,107 @@
 col1	col2
 deallocate prepare stmt;
 drop table t1;
+set @old_max_prepared_stmt_count= @@max_prepared_stmt_count;
+show variables like 'max_prepared_stmt_count';
+Variable_name	Value
+max_prepared_stmt_count	16382
+show variables like 'prepared_stmt_count';
+Variable_name	Value
+prepared_stmt_count	0
+select @@max_prepared_stmt_count, @@prepared_stmt_count;
+@@max_prepared_stmt_count	@@prepared_stmt_count
+16382	0
+set global max_prepared_stmt_count=-1;
+select @@max_prepared_stmt_count;
+@@max_prepared_stmt_count
+0
+set global max_prepared_stmt_count=10000000000000000;
+select @@max_prepared_stmt_count;
+@@max_prepared_stmt_count
+1048576
+set global max_prepared_stmt_count=default;
+select @@max_prepared_stmt_count;
+@@max_prepared_stmt_count
+16382
+set @@max_prepared_stmt_count=1;
+ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL
+set max_prepared_stmt_count=1;
+ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL
+set local max_prepared_stmt_count=1;
+ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL
+set local prepared_stmt_count=0;
+ERROR HY000: Variable 'prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL
+set @@prepared_stmt_count=0;
+ERROR HY000: Variable 'prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL
+set global prepared_stmt_count=1;
+ERROR 42000: Incorrect argument type to variable 'prepared_stmt_count'
+set global max_prepared_stmt_count=1;
+select @@max_prepared_stmt_count;
+@@max_prepared_stmt_count
+1
+set global max_prepared_stmt_count=0;
+select @@max_prepared_stmt_count, @@prepared_stmt_count;
+@@max_prepared_stmt_count	@@prepared_stmt_count
+0	0
+prepare stmt from "select 1";
+ERROR HY000: Unknown error
+select @@prepared_stmt_count;
+@@prepared_stmt_count
+0
+set global max_prepared_stmt_count=1;
+prepare stmt from "select 1";
+select @@prepared_stmt_count;
+@@prepared_stmt_count
+1
+prepare stmt1 from "select 1";
+ERROR HY000: Unknown error
+select @@prepared_stmt_count;
+@@prepared_stmt_count
+1
+deallocate prepare stmt;
+select @@prepared_stmt_count;
+@@prepared_stmt_count
+0
+prepare stmt from "select 1";
+select @@prepared_stmt_count;
+@@prepared_stmt_count
+1
+prepare stmt from "select 2";
+select @@prepared_stmt_count;
+@@prepared_stmt_count
+1
+select @@prepared_stmt_count, @@max_prepared_stmt_count;
+@@prepared_stmt_count	@@max_prepared_stmt_count
+1	1
+set global max_prepared_stmt_count=0;
+prepare stmt from "select 1";
+ERROR HY000: Unknown error
+execute stmt;
+ERROR HY000: Unknown prepared statement handler (stmt) given to EXECUTE
+select @@prepared_stmt_count;
+@@prepared_stmt_count
+0
+prepare stmt from "select 1";
+ERROR HY000: Unknown error
+select @@prepared_stmt_count;
+@@prepared_stmt_count
+0
+set global max_prepared_stmt_count=3;
+select @@max_prepared_stmt_count, @@prepared_stmt_count;
+@@max_prepared_stmt_count	@@prepared_stmt_count
+3	0
+prepare stmt from "select 1";
+prepare stmt from "select 2";
+prepare stmt1 from "select 3";
+prepare stmt2 from "select 4";
+ERROR HY000: Unknown error
+prepare stmt2 from "select 4";
+ERROR HY000: Unknown error
+select @@max_prepared_stmt_count, @@prepared_stmt_count;
+@@max_prepared_stmt_count	@@prepared_stmt_count
+3	3
+deallocate prepare stmt;
+select @@max_prepared_stmt_count, @@prepared_stmt_count;
+@@max_prepared_stmt_count	@@prepared_stmt_count
+3	0
+set global max_prepared_stmt_count= @old_max_prepared_stmt_count;

--- 1.49/mysql-test/t/ps.test	2006-04-07 22:26:15 +04:00
+++ 1.50/mysql-test/t/ps.test	2006-04-07 23:50:37 +04:00
@@ -111,6 +111,9 @@
 prepare stmt1 from @fvar;
 
 drop table t1,t2;
+deallocate prepare stmt3;
+deallocate prepare stmt4;
+deallocate prepare stmt5;
 
 #
 # Bug #4105: Server crash on attempt to prepare a statement with character
@@ -254,6 +257,7 @@
 execute `ü` ;
 set names latin1;
 set names default;
 
 
@@ -802,5 +806,124 @@
 execute stmt using @a,@b;
 deallocate prepare stmt;
 drop table t1;
+
+#
+# Bug#16365 Prepared Statements: DoS with too many open statements
+# Check that the limit @@max_prpeared_stmt_count works.
+#
+# Save the old value
+set @old_max_prepared_stmt_count= @@max_prepared_stmt_count;
+#
+# Disable prepared statement protocol: in this test we set
+# @@max_prepared_stmt_count to 0 or 1 and would like to test the limit
+# manually.
+#
+--disable_ps_protocol
+#
+# A. Check that the new variables are present in SHOW VARIABLES list.
+#
+show variables like 'max_prepared_stmt_count';
+show variables like 'prepared_stmt_count';
+#
+# B. Check that the new variables are selectable.
+#
+select @@max_prepared_stmt_count, @@prepared_stmt_count;
+#
+# C. Check that max_prepared_stmt_count is settable (global only),
+#    whereas prepared_stmt_count is readonly.
+#
+set global max_prepared_stmt_count=-1;
+select @@max_prepared_stmt_count;
+set global max_prepared_stmt_count=10000000000000000;
+select @@max_prepared_stmt_count;
+set global max_prepared_stmt_count=default;
+select @@max_prepared_stmt_count;
+--error 1229 # ER_GLOBAL_VARIABLE
+set @@max_prepared_stmt_count=1;
+--error 1229 # ER_GLOBAL_VARIABLE
+set max_prepared_stmt_count=1;
+--error 1229 # ER_GLOBAL_VARIABLE
+set local max_prepared_stmt_count=1;
+--error 1229 # ER_GLOBAL_VARIABLE
+set local prepared_stmt_count=0;
+--error 1229 # ER_GLOBAL_VARIABLE
+set @@prepared_stmt_count=0;
+--error 1232 # ER_WRONG_TYPE_FOR_VAR
+set global prepared_stmt_count=1;
+# set to a reasonable limit works
+set global max_prepared_stmt_count=1;
+select @@max_prepared_stmt_count;
+#
+# D. Check that the variables actually work.
+#
+set global max_prepared_stmt_count=0;
+select @@max_prepared_stmt_count, @@prepared_stmt_count;
+--error 1105 # ER_UNKNOWN_ERROR
+prepare stmt from "select 1";
+select @@prepared_stmt_count;
+set global max_prepared_stmt_count=1;
+prepare stmt from "select 1";
+select @@prepared_stmt_count;
+--error 1105 # ER_UNKNOWN_ERROR
+prepare stmt1 from "select 1";
+select @@prepared_stmt_count;
+deallocate prepare stmt;
+select @@prepared_stmt_count;
+#
+# E. Check that we can prepare a statement with the same name 
+# successfully, without hitting the limit.
+#
+prepare stmt from "select 1";
+select @@prepared_stmt_count;
+prepare stmt from "select 2";
+select @@prepared_stmt_count;
+#
+# F. We can set the max below the current count. In this case no new 
+# statements should be allowed to prepare.
+#
+select @@prepared_stmt_count, @@max_prepared_stmt_count;
+set global max_prepared_stmt_count=0;
+--error 1105 # ER_UNKNOWN_ERROR
+prepare stmt from "select 1";
+# Result: the old statement is deallocated, the new is not created.
+--error 1243 # ER_UNKNOWN_STMT_HANDLER
+execute stmt;
+select @@prepared_stmt_count;
+--error 1105 # ER_UNKNOWN_ERROR
+prepare stmt from "select 1";
+select @@prepared_stmt_count;
+#
+# G. Show that the variables are up to date even after a connection with all
+# statements in it was terminated.
+#
+set global max_prepared_stmt_count=3;
+select @@max_prepared_stmt_count, @@prepared_stmt_count;
+prepare stmt from "select 1";
+connect (con1,localhost,root,,);
+connection con1;
+prepare stmt from "select 2";
+prepare stmt1 from "select 3";
+--error 1105 # ER_UNKNOWN_ERROR
+prepare stmt2 from "select 4";
+connection default;
+--error 1105 # ER_UNKNOWN_ERROR 
+prepare stmt2 from "select 4";
+select @@max_prepared_stmt_count, @@prepared_stmt_count;
+disconnect con1;
+connection default;
+# Wait for the connection to die: deal with a possible race
+deallocate prepare stmt;
+let $count= `select @@prepared_stmt_count`;
+if ($count)
+{
+--sleep 2
+  let $count= `select @@prepared_stmt_count`;
+}
+select @@max_prepared_stmt_count, @@prepared_stmt_count;
+#
+# Restore the old value.
+#
+set global max_prepared_stmt_count= @old_max_prepared_stmt_count;
+--enable_ps_protocol
 
 # End of 4.1 tests
Thread
bk commit into 4.1 tree (konstantin:1.2504)konstantin7 Apr