List:Commits« Previous MessageNext Message »
From:Nirbhay Choubey Date:October 22 2012 2:04pm
Subject:bzr push into mysql-5.6 branch (nirbhay.choubey:4465 to 4466) Bug#14742760
View as plain text  
 4466 Nirbhay Choubey	2012-10-22
      Bug#14742760 SELECT WITH 12MIO COLUMNS CRASHES MYSQL
                         CLIENT
      
      MySQL client internally used alloca() to allocate
      some memory from stack to keep a track of numeric
      fields. This allocation is unsafe and might result
      in stack overrun if the number of fields is very
      big.
      
      Fixed by adding a logic to switch to my_malloc instead,
      if the requested size exceeds certain limit.
      
      Tested the patch manually for 12M fields.

    modified:
      client/mysql.cc
      include/my_sys.h
      sql/sql_insert.cc
 4465 Tanjot Uppal	2012-10-22
      added server defaults tests and fixed suite/engines/funcs/t/crash_manytables_number.test and suite/engines/funcs/t/crash_manytables_string.test

    added:
      mysql-test/r/host_cache_size_functionality.result
      mysql-test/r/table_definition_cache_functionality.result
      mysql-test/suite/engines/funcs/t/crash_manytables_number.cnf
      mysql-test/suite/engines/funcs/t/crash_manytables_string.cnf
      mysql-test/t/host_cache_size_functionality.test
      mysql-test/t/sort_buffer_size_functionality.test
      mysql-test/t/table_definition_cache_functionality.test
    modified:
      mysql-test/r/sort_buffer_size_functionality.result
      mysql-test/suite/engines/funcs/r/crash_manytables_number.result
      mysql-test/suite/engines/funcs/r/crash_manytables_string.result
      mysql-test/suite/engines/funcs/t/crash_manytables_number.test
      mysql-test/suite/engines/funcs/t/crash_manytables_string.test
      mysql-test/t/query_cache_size_functionality.test
      mysql-test/t/query_cache_type_functionality.test
=== modified file 'client/mysql.cc'
--- a/client/mysql.cc	2012-10-09 10:36:17 +0000
+++ b/client/mysql.cc	2012-10-22 14:00:56 +0000
@@ -62,6 +62,9 @@ static char *server_version= NULL;
 /* Array of options to pass to libemysqld */
 #define MAX_SERVER_ARGS               64
 
+/* Maximum memory limit that can be claimed by alloca(). */
+#define MAX_ALLOCA_SIZE              512
+
 #include "sql_string.h"
 
 extern "C" {
@@ -3655,8 +3658,10 @@ print_table_data(MYSQL_RES *result)
   MYSQL_ROW	cur;
   MYSQL_FIELD	*field;
   bool		*num_flag;
+  size_t        sz;
 
-  num_flag=(bool*) my_alloca(sizeof(bool)*mysql_num_fields(result));
+  sz= sizeof(bool) * mysql_num_fields(result);
+  num_flag= (bool *) my_safe_alloca(sz, MAX_ALLOCA_SIZE);
   if (column_types_flag)
   {
     print_field_types(result);
@@ -3757,7 +3762,7 @@ print_table_data(MYSQL_RES *result)
     (void) tee_fputs("\n", PAGER);
   }
   tee_puts((char*) separator.ptr(), PAGER);
-  my_afree((uchar*) num_flag);
+  my_safe_afree((bool *) num_flag, sz, MAX_ALLOCA_SIZE);
 }
 
 /**

=== modified file 'include/my_sys.h'
--- a/include/my_sys.h	2012-08-03 04:58:55 +0000
+++ b/include/my_sys.h	2012-10-22 14:00:56 +0000
@@ -159,6 +159,22 @@ extern void *my_memdup(const void *from,
 extern char *my_strdup(const char *from,myf MyFlags);
 extern char *my_strndup(const char *from, size_t length,
 				   myf MyFlags);
+
+/*
+  Switch to my_malloc() if the memory block to be allocated is bigger than
+  max_alloca_sz.
+*/
+#ifndef HAVE_ALLOCA
+#define my_safe_alloca(size, max_alloca_sz) my_alloca(size)
+#define my_safe_afree(ptr, size, max_alloca_sz) my_afree(ptr)
+#else
+#define my_safe_alloca(size, max_alloca_sz) ((size <= max_alloca_sz) ? \
+                                             my_alloca(size) : \
+                                             my_malloc(size, MYF(0)))
+#define my_safe_afree(ptr, size, max_alloca_sz) if (size > max_alloca_sz) \
+                                               my_free(ptr)
+#endif                                          /* #ifndef HAVE_ALLOCA */
+
 #if !defined(DBUG_OFF) || defined(HAVE_VALGRIND)
 /**
   Put bad content in memory to be sure it will segfault if dereferenced.

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2012-09-22 17:06:24 +0000
+++ b/sql/sql_insert.cc	2012-10-22 14:00:56 +0000
@@ -102,16 +102,6 @@ static void unlink_blobs(register TABLE
 #endif
 static bool check_view_insertability(THD *thd, TABLE_LIST *view);
 
-/* Define to force use of my_malloc() if the allocated memory block is big */
-
-#ifndef HAVE_ALLOCA
-#define my_safe_alloca(size, min_length) my_alloca(size)
-#define my_safe_afree(ptr, size, min_length) my_afree(ptr)
-#else
-#define my_safe_alloca(size, min_length) ((size <= min_length) ? my_alloca(size) : my_malloc(size,MYF(0)))
-#define my_safe_afree(ptr, size, min_length) if (size > min_length) my_free(ptr)
-#endif
-
 /*
   Check that insert/update fields are from the same single table of a view.
 

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-5.6 branch (nirbhay.choubey:4465 to 4466) Bug#14742760Nirbhay Choubey23 Oct