From c9ab025dcd7f74ff9d6db09a584980383c840853 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Thu, 9 Sep 2010 14:28:47 -0600 Subject: [PATCH 1/6] Bug#56521 Assertion failed: (m_state == 2), function allocated_to_free, pfs_lock.h (138) Before this fix, it was possible to build the server: - with the performance schema - with a dummy implementation of my_atomic (MY_ATOMIC_MODE_DUMMY). In this case, the resulting binary will just crash, as this configuration is not supported. This fix enforces that the build will fail with a compilation error in this configuration, instead of resulting in a broken binary. --- storage/perfschema/ha_perfschema.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/storage/perfschema/ha_perfschema.cc b/storage/perfschema/ha_perfschema.cc index 0fac734f7a0..b7b6b03f8c5 100644 --- a/storage/perfschema/ha_perfschema.cc +++ b/storage/perfschema/ha_perfschema.cc @@ -19,6 +19,7 @@ */ #include "my_global.h" +#include "my_atomic.h" #include "my_pthread.h" #include "sql_plugin.h" #include "mysql/plugin.h" @@ -28,6 +29,17 @@ #include "pfs_instr_class.h" #include "pfs_instr.h" +#ifdef MY_ATOMIC_MODE_DUMMY +/* + The performance schema can can not function with MY_ATOMIC_MODE_DUMMY, + a fully functional implementation of MY_ATOMIC should be used instead. + If the build fails with this error message: + - either use a different ./configure --with-atomic-ops option + - or do not build with the performance schema. +*/ +#error "The performance schema needs a functional MY_ATOMIC implementation." +#endif + handlerton *pfs_hton= NULL; static handler* pfs_create_handler(handlerton *hton, From 2779f0aad1af99abd8295d41c99e208668ef317e Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Thu, 9 Sep 2010 15:33:35 -0600 Subject: [PATCH 2/6] Bug#56324 Race Condition while shutting down MySQL: "PSI_server" Before this fix, the server could crash during shutdown, due to race conditions, that occured when killing the server. In particular, the performance schema instrumentation handle, PSI_server, and the performance schema itself would be cleaned up too soon, causing race conditions with a running kill server thread. The specifics of the race condition found are that: the main thread executing "PSI_server= NULL" can cause crashes in other threads still running, which are executing "if (PSI_server != NULL) PSI_server->xxx()" as part of the performance schema instrumentation. While the bug was reported for the kill server thread, in theory the same crash could happen with the signal thread, as found by code analysis. The correct fix would be to only shutdown the performance schema and set PSI_server to NULL after every other thread is guaranteed to be completed, including the kill_server_thread. However, due to the existing mysqld server design, this is not the case. See in particular bug number 56666. The work around used to fix this race condition is to simply not perform the call to shutdown_performance_schema() when the server exits, and to keep the PSI_server pointer unchanged. This will cause memory leaks to be reported by tools like valgrind, but no memory leak actually happen because the process is about to exit(). As a result, the file mysql-test/valgrind.supp has been updated to filter out these false positive messages. This code has been tested with running in a loop the following tests in parallel, which have been known to fail with race conditions in the past: - rpl_change_master - binlog_max_extension - events_restart - rpl_heartbeat_basic and no crash of test failure has been seen with the changed code. --- mysql-test/valgrind.supp | 25 +++++++++++++++++++++++++ sql/mysqld.cc | 32 ++++++++++++++++++++------------ 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index 83896378883..4b323b0bbfc 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -745,3 +745,28 @@ Memcheck:Addr1 fun:buf_buddy_relocate } + +# +# See related Bug#56666 +# Race condition between the server main thread and the kill server thread. +# +# Because of this race condition, the call to shutdown_performance_schema() +# was commented in sql/mysqld.cc, causing the reported leaks. +# + +{ + missing shutdown_performance_schema 1 + Memcheck:Leak + fun:malloc + fun:_Z10pfs_mallocmi +} + +{ + missing shutdown_performance_schema 2 + Memcheck:Leak + fun:malloc + fun:my_malloc + fun:_lf_alloc_new + fun:lf_hash_insert +} + diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6dd74eb299a..854d314d7d5 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1395,6 +1395,12 @@ static void mysqld_exit(int exit_code) mysql_audit_finalize(); clean_up_mutexes(); clean_up_error_log_mutex(); +#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE + /* + Bug#56666 needs to be fixed before calling: + shutdown_performance_schema(); + */ +#endif my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); exit(exit_code); /* purecov: inspected */ } @@ -2732,6 +2738,11 @@ pthread_handler_t signal_hand(void *arg __attribute__((unused))) if (!abort_loop) { abort_loop=1; // mark abort for threads +#ifdef HAVE_PSI_INTERFACE + /* Delete the instrumentation for the signal thread */ + if (likely(PSI_server != NULL)) + PSI_server->delete_current_thread(); +#endif #ifdef USE_ONE_SIGNAL_HAND pthread_t tmp; if (mysql_thread_create(0, /* Not instrumented */ @@ -4587,6 +4598,15 @@ int mysqld_main(int argc, char **argv) #endif #endif /* __WIN__ */ +#ifdef HAVE_PSI_INTERFACE + /* + Disable the main thread instrumentation, + to avoid recording events during the shutdown. + */ + if (PSI_server) + PSI_server->delete_current_thread(); +#endif + /* Wait until cleanup is done */ mysql_mutex_lock(&LOCK_thread_count); while (!ready_to_exit) @@ -4604,18 +4624,6 @@ int mysqld_main(int argc, char **argv) } #endif clean_up(1); -#ifdef HAVE_PSI_INTERFACE - /* - Disable the instrumentation, to avoid recording events - during the shutdown. - */ - if (PSI_server) - { - PSI_server->delete_current_thread(); - PSI_server= NULL; - } - shutdown_performance_schema(); -#endif mysqld_exit(0); } From 197a2dba306446d779bb730fbe7cc5ca6e961b7c Mon Sep 17 00:00:00 2001 From: Tor Didriksen Date: Fri, 10 Sep 2010 11:10:38 +0200 Subject: [PATCH 3/6] Header files should be self-contained --- storage/perfschema/ha_perfschema.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/perfschema/ha_perfschema.cc b/storage/perfschema/ha_perfschema.cc index b7b6b03f8c5..e5e324d6c6b 100644 --- a/storage/perfschema/ha_perfschema.cc +++ b/storage/perfschema/ha_perfschema.cc @@ -19,8 +19,8 @@ */ #include "my_global.h" -#include "my_atomic.h" #include "my_pthread.h" +#include "my_atomic.h" #include "sql_plugin.h" #include "mysql/plugin.h" #include "ha_perfschema.h" From 651d597e2ff7f46c856943c8839bff201fef8424 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Mon, 13 Sep 2010 17:19:39 -0600 Subject: [PATCH 4/6] Bug#53102 perfschema.pfs_upgrade fails when executed direct after mysql_upgrade Implemented post review comments. Added --force to the mysql_upgrade command in the test scripts, so that the test output does not depends on whether other tests involving an upgrade have been executed or not in the same test suite execution. --- mysql-test/suite/perfschema/include/upgrade_check.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/perfschema/include/upgrade_check.inc b/mysql-test/suite/perfschema/include/upgrade_check.inc index 935a71ab065..3620e80002f 100644 --- a/mysql-test/suite/perfschema/include/upgrade_check.inc +++ b/mysql-test/suite/perfschema/include/upgrade_check.inc @@ -18,7 +18,7 @@ # --error 1 ---exec $MYSQL_UPGRADE --skip-verbose > $out_file 2> $err_file +--exec $MYSQL_UPGRADE --skip-verbose --force > $out_file 2> $err_file # Verify that mysql_upgrade complained about the performance_schema --cat_file $err_file From 93e7e5f9d94c10f94f5d19ae10ebe9adcf443e78 Mon Sep 17 00:00:00 2001 From: Olav Sandstaa Date: Wed, 15 Sep 2010 13:33:22 +0200 Subject: [PATCH 5/6] 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 | 6 +----- include/mysql/service_my_snprintf.h | 2 +- strings/my_vsnprintf.c | 14 ++++++++------ unittest/mysys/my_vsnprintf-t.c | 11 ++++++++++- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/dbug/dbug.c b/dbug/dbug.c index fd87669b8ca..4968d9e0568 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -1335,15 +1335,11 @@ void _db_doprnt_(const char *format,...) * This function is intended as a * vfprintf clone with consistent, platform independent output for * problematic formats like %p, %zd and %lld. - * However: full functionality for my_vsnprintf has not been backported yet, - * so code using "%g" or "%f" will have undefined behaviour. */ static void DbugVfprintf(FILE *stream, const char* format, va_list args) { char cvtbuf[1024]; - size_t len; - /* Do not use my_vsnprintf, it does not support "%g". */ - len = vsnprintf(cvtbuf, sizeof(cvtbuf), format, args); + (void) my_vsnprintf(cvtbuf, sizeof(cvtbuf), format, args); (void) fprintf(stream, "%s\n", cvtbuf); } diff --git a/include/mysql/service_my_snprintf.h b/include/mysql/service_my_snprintf.h index d7f8d07e110..f6b4aa39dc5 100644 --- a/include/mysql/service_my_snprintf.h +++ b/include/mysql/service_my_snprintf.h @@ -53,7 +53,7 @@ can be 'l', 'll', or 'z'. Supported formats are 's' (null pointer is accepted, printed as - "(null)"), 'b' (extension, see below), 'c', 'd', 'u', 'x', 'o', + "(null)"), 'b' (extension, see below), 'c', 'd', 'i', 'u', 'x', 'o', 'X', 'p' (works as 0x%x). Standard syntax for positional arguments $n is supported. diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index 251c3905d5a..1284203f739 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -255,7 +255,7 @@ static char *process_int_arg(char *to, char *end, size_t length, if ((to_length= (size_t) (end-to)) < 16 || length) store_start= buff; - if (arg_type == 'd') + if (arg_type == 'd' || arg_type == 'i') store_end= longlong10_to_str(par, store_start, -10); else if (arg_type == 'u') store_end= longlong10_to_str(par, store_start, 10); @@ -399,6 +399,7 @@ start: args_arr[i].double_arg= va_arg(ap, double); break; case 'd': + case 'i': case 'u': case 'x': case 'X': @@ -406,7 +407,7 @@ start: case 'p': if (args_arr[i].have_longlong) args_arr[i].longlong_arg= va_arg(ap,longlong); - else if (args_arr[i].arg_type == 'd') + else if (args_arr[i].arg_type == 'd' || args_arr[i].arg_type == 'i') args_arr[i].longlong_arg= va_arg(ap, int); else args_arr[i].longlong_arg= va_arg(ap, uint); @@ -458,6 +459,7 @@ start: break; } case 'd': + case 'i': case 'u': case 'x': case 'X': @@ -472,7 +474,7 @@ start: if (args_arr[print_arr[i].arg_idx].have_longlong) larg = args_arr[print_arr[i].arg_idx].longlong_arg; - else if (print_arr[i].arg_type == 'd') + else if (print_arr[i].arg_type == 'd' || print_arr[i].arg_type == 'i' ) larg = (int) args_arr[print_arr[i].arg_idx].longlong_arg; else larg= (uint) args_arr[print_arr[i].arg_idx].longlong_arg; @@ -615,8 +617,8 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n, to= process_dbl_arg(to, end, width, d, *fmt); continue; } - else if (*fmt == 'd' || *fmt == 'u' || *fmt == 'x' || *fmt == 'X' || - *fmt == 'p' || *fmt == 'o') + else if (*fmt == 'd' || *fmt == 'i' || *fmt == 'u' || *fmt == 'x' || + *fmt == 'X' || *fmt == 'p' || *fmt == 'o') { /* Integer parameter */ longlong larg; @@ -625,7 +627,7 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, char *to, size_t n, if (have_longlong) larg = va_arg(ap,longlong); - else if (*fmt == 'd') + else if (*fmt == 'd' || *fmt == 'i') larg = va_arg(ap, int); else larg= va_arg(ap, uint); diff --git a/unittest/mysys/my_vsnprintf-t.c b/unittest/mysys/my_vsnprintf-t.c index 4ef6c310c8f..e7f37774f85 100644 --- a/unittest/mysys/my_vsnprintf-t.c +++ b/unittest/mysys/my_vsnprintf-t.c @@ -31,7 +31,7 @@ void test1(const char *res, const char *fmt, ...) int main(void) { - plan(54); + plan(58); test1("Constant string", "Constant string"); @@ -44,6 +44,8 @@ int main(void) "Format specifier c %c", '!'); test1("Format specifier d 1", "Format specifier d %d", 1); + test1("Format specifier i 1", + "Format specifier i %i", 1); test1("Format specifier u 2", "Format specifier u %u", 2); test1("Format specifier o 375", @@ -77,6 +79,9 @@ int main(void) test1("Length modifiers work: 1 * -1 * 2 * 3", "Length modifiers work: %d * %ld * %lld * %zd", 1, -1L, 2LL, (size_t)3); + test1("Length modifiers work: 1 * -1 * 2 * 3", + "Length modifiers work: %i * %li * %lli * %zd", 1, -1L, 2LL, (size_t)3); + test1("long long X: 123456789abcdef0", "long long X: %llx", 0x123456789abcdef0LL); @@ -121,6 +126,10 @@ int main(void) "Hello int, %d", 1); test1("Hello int, -1", "Hello int, %d", -1); + test1("Hello int, 1", + "Hello int, %i", 1); + test1("Hello int, -1", + "Hello int, %i", -1); test1("Hello string 'I am a string'", "Hello string '%s'", "I am a string"); test1("Hello hack hack hack hack hack hack hack 1", From 2e4717ffcd8a3c7a025be78a7328ec219bed97db Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Wed, 15 Sep 2010 12:20:48 -0600 Subject: [PATCH 6/6] 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. --- mysql-test/suite/perfschema/r/checksum.result | 34 ++++++++++ mysql-test/suite/perfschema/t/checksum.test | 64 +++++++++++++++++++ storage/perfschema/table_events_waits.cc | 20 ++++-- storage/perfschema/table_events_waits.h | 2 +- 4 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 mysql-test/suite/perfschema/r/checksum.result create mode 100644 mysql-test/suite/perfschema/t/checksum.test diff --git a/mysql-test/suite/perfschema/r/checksum.result b/mysql-test/suite/perfschema/r/checksum.result new file mode 100644 index 00000000000..323cb303dae --- /dev/null +++ b/mysql-test/suite/perfschema/r/checksum.result @@ -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; diff --git a/mysql-test/suite/perfschema/t/checksum.test b/mysql-test/suite/perfschema/t/checksum.test new file mode 100644 index 00000000000..d7fdd7b4c2c --- /dev/null +++ b/mysql-test/suite/perfschema/t/checksum.test @@ -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 + diff --git a/storage/perfschema/table_events_waits.cc b/storage/perfschema/table_events_waits.cc index 5e5972b68f1..d34f6fbe722 100644 --- a/storage/perfschema/table_events_waits.cc +++ b/storage/perfschema/table_events_waits.cc @@ -187,7 +187,7 @@ void table_events_waits_common::clear_object_columns() */ 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(bool thread_own_wait, 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: diff --git a/storage/perfschema/table_events_waits.h b/storage/perfschema/table_events_waits.h index 2aa88b54be4..aa4edb4a368 100644 --- a/storage/perfschema/table_events_waits.h +++ b/storage/perfschema/table_events_waits.h @@ -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;