diff options
author | Sujatha <sujatha.sivakumar@mariadb.com> | 2019-12-18 15:02:56 +0530 |
---|---|---|
committer | Sujatha <sujatha.sivakumar@mariadb.com> | 2020-01-07 18:27:05 +0530 |
commit | 2187f1c2caacd5d6dcb93789473dbaffc9613776 (patch) | |
tree | 1203a51c010be482dc338ce41c660daaf67bdbe3 /sql/log_event.cc | |
parent | d6fa69e4be945da174ae3445dc8203ece689f048 (diff) | |
download | mariadb-git-2187f1c2caacd5d6dcb93789473dbaffc9613776.tar.gz |
MDEV-18046: Assortment of crashes, assertion failures and ASAN errors in mysql_show_binlog_events
Problem:
========
SHOW BINLOG EVENTS FROM <pos> reports following ASAN error
"heap-buffer-overflow on address" and some times it asserts.
Table_map_log_event::Table_map_log_event(const char*, uint,
const Format_description_log_event*)
Assertion `m_field_metadata_size <= (m_colcnt * 2)' failed.
Fix:
===
**Part7: Avoid reading out of buffer**
Converted debug assert to error handler code.
Diffstat (limited to 'sql/log_event.cc')
-rw-r--r-- | sql/log_event.cc | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc index 65ce94f2695..577b9f1a149 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -11013,7 +11013,6 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len, uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1]; DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d", event_len, common_header_len, post_header_len)); - /* Don't print debug messages when running valgrind since they can trigger false warnings. @@ -11022,6 +11021,9 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len, DBUG_DUMP("event buffer", (uchar*) buf, event_len); #endif + if (event_len < (uint)(common_header_len + post_header_len)) + DBUG_VOID_RETURN; + /* Read the post-header */ const char *post_start= buf + common_header_len; @@ -11084,15 +11086,24 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len, if (bytes_read < event_len) { m_field_metadata_size= net_field_length(&ptr_after_colcnt); - DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2)); - uint num_null_bytes= (m_colcnt + 7) / 8; - m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME), - &m_null_bits, num_null_bytes, - &m_field_metadata, m_field_metadata_size, - NULL); - memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size); - ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size; - memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes); + if(m_field_metadata_size <= (m_colcnt * 2)) + { + uint num_null_bytes= (m_colcnt + 7) / 8; + m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME), + &m_null_bits, num_null_bytes, + &m_field_metadata, m_field_metadata_size, + NULL); + memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size); + ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size; + memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes); + } + else + { + m_coltype= NULL; + my_free(m_memory); + m_memory= NULL; + DBUG_VOID_RETURN; + } } } |