List:Commits« Previous MessageNext Message »
From:Marc Alff Date:September 15 2010 8:24pm
Subject:bzr push into mysql-5.5-bugfixing branch (marc.alff:3206 to 3207) Bug#56761
View as plain text  
 3207 Marc Alff	2010-09-15
      Bug#56761 Segfault on CHECKSUM TABLE performance_schema.EVENTS_WAITS_HISTORY EXTENDED
      
      Before this fix, the server could crash inside a memcpy when reading data
      from the EVENTS_WAITS_CURRENT / HISTORY / HISTORY_LONG  tables.
      
      The root cause is that the length used in a memcpy could be corrupted,
      when another thread writes data in the wait record being read.
      Reading unsafe data is ok, per design choice, and the code does sanitize
      the data in general, but did not sanitize the length given to memcpy.
      
      The fix is to also sanitize the schema name / object name / file name
      length when extracting the data to produce a row.

    added:
      mysql-test/suite/perfschema/r/checksum.result
      mysql-test/suite/perfschema/t/checksum.test
    modified:
      storage/perfschema/table_events_waits.cc
      storage/perfschema/table_events_waits.h
 3206 Olav Sandstaa	2010-09-15
      Fix for Bug#54478 "mysqld crashes during boot when running mtr with --debug option"
            
      The crash during boot was caused by a DBUG_PRINT statement in fill_schema_schemata() (in
      sql_show.cc). This DBUG_PRINT statement contained several instances of %s in the format 
      string and for one of these we gave a NULL pointer as the argument. This caused the
      call to vsnprintf() to crash when running on Solaris.
            
      The fix for this problem is to replace the call to vsnprintf() with my_vsnprintf()
      which handles that a NULL pointer is passed as argumens for %s.
      
      This patch also extends my_vsnprintf() to support %i in the format string.
     @ dbug/dbug.c
        Replace the use of vsnprintf() with my_vsnprintf(). On some platforms
        vsnprintf() did not handle that a NULL pointer was given as an argument
        for a %s in the format string.
     @ include/mysql/service_my_snprintf.h
        Add support for %i in format string to my_vsnprintf().
     @ strings/my_vsnprintf.c
        Add support for %i in format string to my_vsnprintf().
     @ unittest/mysys/my_vsnprintf-t.c
        Add unit tests for %i in format string to my_vsnprintf().

    modified:
      dbug/dbug.c
      include/mysql/service_my_snprintf.h
      strings/my_vsnprintf.c
      unittest/mysys/my_vsnprintf-t.c
=== added file 'mysql-test/suite/perfschema/r/checksum.result'
--- a/mysql-test/suite/perfschema/r/checksum.result	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/perfschema/r/checksum.result	2010-09-15 18:20:48 +0000
@@ -0,0 +1,34 @@
+checksum table performance_schema.COND_INSTANCES;
+checksum table performance_schema.EVENTS_WAITS_CURRENT;
+checksum table performance_schema.EVENTS_WAITS_HISTORY;
+checksum table performance_schema.EVENTS_WAITS_HISTORY_LONG;
+checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE;
+checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME;
+checksum table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME;
+checksum table performance_schema.FILE_INSTANCES;
+checksum table performance_schema.FILE_SUMMARY_BY_EVENT_NAME;
+checksum table performance_schema.FILE_SUMMARY_BY_INSTANCE;
+checksum table performance_schema.MUTEX_INSTANCES;
+checksum table performance_schema.PERFORMANCE_TIMERS;
+checksum table performance_schema.RWLOCK_INSTANCES;
+checksum table performance_schema.SETUP_CONSUMERS;
+checksum table performance_schema.SETUP_INSTRUMENTS;
+checksum table performance_schema.SETUP_TIMERS;
+checksum table performance_schema.THREADS;
+checksum table performance_schema.COND_INSTANCES extended;
+checksum table performance_schema.EVENTS_WAITS_CURRENT extended;
+checksum table performance_schema.EVENTS_WAITS_HISTORY extended;
+checksum table performance_schema.EVENTS_WAITS_HISTORY_LONG extended;
+checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE extended;
+checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME extended;
+checksum table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME extended;
+checksum table performance_schema.FILE_INSTANCES extended;
+checksum table performance_schema.FILE_SUMMARY_BY_EVENT_NAME extended;
+checksum table performance_schema.FILE_SUMMARY_BY_INSTANCE extended;
+checksum table performance_schema.MUTEX_INSTANCES extended;
+checksum table performance_schema.PERFORMANCE_TIMERS extended;
+checksum table performance_schema.RWLOCK_INSTANCES extended;
+checksum table performance_schema.SETUP_CONSUMERS extended;
+checksum table performance_schema.SETUP_INSTRUMENTS extended;
+checksum table performance_schema.SETUP_TIMERS extended;
+checksum table performance_schema.THREADS extended;

=== added file 'mysql-test/suite/perfschema/t/checksum.test'
--- a/mysql-test/suite/perfschema/t/checksum.test	1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/perfschema/t/checksum.test	2010-09-15 18:20:48 +0000
@@ -0,0 +1,64 @@
+# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+# Tests for PERFORMANCE_SCHEMA
+
+--source include/not_embedded.inc
+--source include/have_perfschema.inc
+
+#
+# The checksum value itself is random (data is volatile),
+# just testing that this does not crash
+#
+--disable_result_log
+
+checksum table performance_schema.COND_INSTANCES;
+checksum table performance_schema.EVENTS_WAITS_CURRENT;
+checksum table performance_schema.EVENTS_WAITS_HISTORY;
+checksum table performance_schema.EVENTS_WAITS_HISTORY_LONG;
+checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE;
+checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME;
+checksum table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME;
+checksum table performance_schema.FILE_INSTANCES;
+checksum table performance_schema.FILE_SUMMARY_BY_EVENT_NAME;
+checksum table performance_schema.FILE_SUMMARY_BY_INSTANCE;
+checksum table performance_schema.MUTEX_INSTANCES;
+checksum table performance_schema.PERFORMANCE_TIMERS;
+checksum table performance_schema.RWLOCK_INSTANCES;
+checksum table performance_schema.SETUP_CONSUMERS;
+checksum table performance_schema.SETUP_INSTRUMENTS;
+checksum table performance_schema.SETUP_TIMERS;
+checksum table performance_schema.THREADS;
+
+checksum table performance_schema.COND_INSTANCES extended;
+checksum table performance_schema.EVENTS_WAITS_CURRENT extended;
+checksum table performance_schema.EVENTS_WAITS_HISTORY extended;
+checksum table performance_schema.EVENTS_WAITS_HISTORY_LONG extended;
+checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE extended;
+checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME extended;
+checksum table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME extended;
+checksum table performance_schema.FILE_INSTANCES extended;
+checksum table performance_schema.FILE_SUMMARY_BY_EVENT_NAME extended;
+checksum table performance_schema.FILE_SUMMARY_BY_INSTANCE extended;
+checksum table performance_schema.MUTEX_INSTANCES extended;
+checksum table performance_schema.PERFORMANCE_TIMERS extended;
+checksum table performance_schema.RWLOCK_INSTANCES extended;
+checksum table performance_schema.SETUP_CONSUMERS extended;
+checksum table performance_schema.SETUP_INSTRUMENTS extended;
+checksum table performance_schema.SETUP_TIMERS extended;
+checksum table performance_schema.THREADS extended;
+
+--enable_result_log
+

=== modified file 'storage/perfschema/table_events_waits.cc'
--- a/storage/perfschema/table_events_waits.cc	2010-08-12 09:51:58 +0000
+++ b/storage/perfschema/table_events_waits.cc	2010-09-15 18:20:48 +0000
@@ -187,7 +187,7 @@ void table_events_waits_common::clear_ob
 */
 void table_events_waits_common::make_row(bool thread_own_wait,
                                          PFS_thread *pfs_thread,
-                                         PFS_events_waits *wait)
+                                         volatile PFS_events_waits *wait)
 {
   pfs_lock lock;
   PFS_thread *safe_thread;
@@ -251,21 +251,27 @@ void table_events_waits_common::make_row
   case WAIT_CLASS_TABLE:
     m_row.m_object_type= "TABLE";
     m_row.m_object_type_length= 5;
-    memcpy(m_row.m_object_schema, wait->m_schema_name,
-           wait->m_schema_name_length);
     m_row.m_object_schema_length= wait->m_schema_name_length;
-    memcpy(m_row.m_object_name, wait->m_object_name,
-           wait->m_object_name_length);
+    if (unlikely((m_row.m_object_schema_length == 0) ||
+                 (m_row.m_object_schema_length > sizeof(m_row.m_object_schema))))
+      return;
+    memcpy(m_row.m_object_schema, wait->m_schema_name, m_row.m_object_schema_length);
     m_row.m_object_name_length= wait->m_object_name_length;
+    if (unlikely((m_row.m_object_name_length == 0) ||
+                 (m_row.m_object_name_length > sizeof(m_row.m_object_name))))
+      return;
+    memcpy(m_row.m_object_name, wait->m_object_name, m_row.m_object_name_length);
     safe_class= &global_table_class;
     break;
   case WAIT_CLASS_FILE:
     m_row.m_object_type= "FILE";
     m_row.m_object_type_length= 4;
     m_row.m_object_schema_length= 0;
-    memcpy(m_row.m_object_name, wait->m_object_name,
-           wait->m_object_name_length);
     m_row.m_object_name_length= wait->m_object_name_length;
+    if (unlikely((m_row.m_object_name_length == 0) ||
+                 (m_row.m_object_name_length > sizeof(m_row.m_object_name))))
+      return;
+    memcpy(m_row.m_object_name, wait->m_object_name, m_row.m_object_name_length);
     safe_class= sanitize_file_class((PFS_file_class*) wait->m_class);
     break;
   case NO_WAIT_CLASS:

=== modified file 'storage/perfschema/table_events_waits.h'
--- a/storage/perfschema/table_events_waits.h	2010-07-16 00:06:33 +0000
+++ b/storage/perfschema/table_events_waits.h	2010-09-15 18:20:48 +0000
@@ -137,7 +137,7 @@ protected:
   void clear_object_columns();
 
   void make_row(bool thread_own_wait, PFS_thread *pfs_thread,
-                PFS_events_waits *wait);
+                volatile PFS_events_waits *wait);
 
   /** Current row. */
   row_events_waits m_row;


Attachment: [text/bzr-bundle] bzr/marc.alff@oracle.com-20100915182048-ot7u834d8618xhm4.bundle
Thread
bzr push into mysql-5.5-bugfixing branch (marc.alff:3206 to 3207) Bug#56761Marc Alff15 Sep