From b3c4bc6e7dbc1811a2cf11dae822dc9166d9b36b Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 12 Nov 2007 22:02:12 +0100 Subject: [PATCH 1/3] BUG#31793 (log event corruption causes crash): Corrections to get_str_len_and_pointer(). sql/log_event.cc: Adding missing return at end of get_str_len_and_pointer() and correcting computation of missing bytes. --- sql/log_event.cc | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index f2b7fcbd236..5c3fcf2f86b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1436,11 +1436,12 @@ get_str_len_and_pointer(const Log_event::Byte **src, if (length > 0) { if (*src + length >= end) - return *src + length - end; // Number of bytes missing + return *src + length - end + 1; // Number of bytes missing *dst= (char *)*src + 1; // Will be copied later } *len= length; - (*src)+= *len + 1; + *src+= length + 1; + return 0; } static void copy_str_and_move(const char **src, @@ -1454,6 +1455,23 @@ static void copy_str_and_move(const char **src, } +static char const *code_name(int code) { + char buf[255]; + switch (code) { + case Q_FLAGS2_CODE: return "Q_FLAGS2_CODE"; + case Q_SQL_MODE_CODE: return "Q_SQL_MODE_CODE"; + case Q_CATALOG_CODE: return "Q_CATALOG_CODE"; + case Q_AUTO_INCREMENT: return "Q_AUTO_INCREMENT"; + case Q_CHARSET_CODE: return "Q_CHARSET_CODE"; + case Q_TIME_ZONE_CODE: return "Q_TIME_ZONE_CODE"; + case Q_CATALOG_NZ_CODE: return "Q_CATALOG_NZ_CODE"; + case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE"; + case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE"; + } + sprintf(buf, "CODE#%d", code); + return buf; +} + /** Macro to check that there is enough space to read from memory. @@ -1461,13 +1479,15 @@ static void copy_str_and_move(const char **src, @param END End of memory @param CNT Number of bytes that should be read. */ -#define CHECK_SPACE(PTR,END,CNT) \ - do { \ - DBUG_ASSERT((PTR) + (CNT) <= (END)); \ - if ((PTR) + (CNT) > (END)) { \ - query= 0; \ - DBUG_VOID_RETURN; \ - } \ +#define CHECK_SPACE(PTR,END,CNT) \ + do { \ + DBUG_PRINT("info", ("Read %s", code_name(pos[-1]))); \ + DBUG_ASSERT((PTR) + (CNT) <= (END)); \ + if ((PTR) + (CNT) > (END)) { \ + DBUG_PRINT("info", ("query= 0")); \ + query= 0; \ + DBUG_VOID_RETURN; \ + } \ } while (0) /* @@ -1527,8 +1547,10 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, be even bigger, but this will suffice to catch most corruption errors that can lead to a crash. */ - if (status_vars_len >= min(data_len + 1, MAX_SIZE_LOG_EVENT_STATUS)) + if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS)) { + DBUG_PRINT("info", ("status_vars_len: %d; data_len: %d; query= 0", + status_vars_len, data_len)); query= 0; DBUG_VOID_RETURN; } @@ -1571,8 +1593,11 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, break; } case Q_CATALOG_NZ_CODE: + DBUG_PRINT("info", ("case Q_CATALOG_NZ_CODE; pos: 0x%lx; end: 0x%lx", + pos, end)); if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end)) { + DBUG_PRINT("info", ("query= 0")); query= 0; DBUG_VOID_RETURN; } @@ -1595,6 +1620,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, { if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end)) { + DBUG_PRINT("info", ("Q_TIME_ZONE_CODE: query= 0")); query= 0; DBUG_VOID_RETURN; } @@ -2124,6 +2150,7 @@ end: */ thd->catalog= 0; thd->set_db(NULL, 0); /* will free the current database */ + DBUG_PRINT("info", ("end: query= 0")); thd->query= 0; // just to be sure thd->query_length= 0; VOID(pthread_mutex_unlock(&LOCK_thread_count)); From 8cc379ebab5412846c5add52f9a4e3fdb32aa54a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Nov 2007 09:01:42 +0100 Subject: [PATCH 2/3] Fixes to eliminate warnings. --- sql/log_event.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 5c3fcf2f86b..13c15924210 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1455,8 +1455,10 @@ static void copy_str_and_move(const char **src, } -static char const *code_name(int code) { - char buf[255]; +static char const * +code_name(int code) +{ + static char buf[255]; switch (code) { case Q_FLAGS2_CODE: return "Q_FLAGS2_CODE"; case Q_SQL_MODE_CODE: return "Q_SQL_MODE_CODE"; @@ -1549,7 +1551,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, */ if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS)) { - DBUG_PRINT("info", ("status_vars_len: %d; data_len: %d; query= 0", + DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0", status_vars_len, data_len)); query= 0; DBUG_VOID_RETURN; @@ -1594,7 +1596,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, } case Q_CATALOG_NZ_CODE: DBUG_PRINT("info", ("case Q_CATALOG_NZ_CODE; pos: 0x%lx; end: 0x%lx", - pos, end)); + (ulong) pos, (ulong) end)); if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end)) { DBUG_PRINT("info", ("query= 0")); From c1b3466f799bf68b1f5151a2656b91ca1aea85e8 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 13 Nov 2007 09:43:29 +0100 Subject: [PATCH 3/3] Elimination of warning for unused function code_name() in non-debug mode. --- sql/log_event.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql/log_event.cc b/sql/log_event.cc index 13c15924210..d22973d12a3 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1455,6 +1455,7 @@ static void copy_str_and_move(const char **src, } +#ifndef DBUG_OFF static char const * code_name(int code) { @@ -1473,6 +1474,7 @@ code_name(int code) sprintf(buf, "CODE#%d", code); return buf; } +#endif /** Macro to check that there is enough space to read from memory.