summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Malyavin <nikitamalyavin@gmail.com>2023-04-11 00:11:21 +0300
committerNikita Malyavin <nikitamalyavin@gmail.com>2023-05-06 00:00:27 +0300
commit47f5c7ae7e452225bd8f0f3c88ca1b5be36c85a7 (patch)
tree27f7e524afa8f39409f35a297f452962ffeb4202
parenta50bcc2a70037bfe78b7d582d7051159899e868c (diff)
downloadmariadb-git-47f5c7ae7e452225bd8f0f3c88ca1b5be36c85a7.tar.gz
MDEV-30945 RPL tests are failing with MSAN use-of-uninitialized-value
...in bitmap_intersect m_cols_ai was accessed during the Delete event, however this field is only related to Updates. Moving it to Update_rows_event would require too much effort. So instead: * Only access m_cols_ai in Update events (conditional branch is added in Rows_log_event::do_add_row_data) * Clean up m_cols_ai operations in Rows_log_event constructor. m_cols_ai.bitmap is first set to NULL, indicating invalid event. Then it is initialized: -> For Update events, a new bitmap is created. -> For other events, debug mode, m_cols_ai.bitmap is set to 1, indicating that the value is correct, but it shouldn't be accessed. To make sure we'll have a failure, n_bits is also set to 1. -> In release mode, m_cols_ai mirrors m_cols, providing extra safety in production.
-rw-r--r--sql/log_event.cc21
-rw-r--r--sql/log_event_server.cc3
2 files changed, 15 insertions, 9 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index eb4e842141e..5a32366f4ab 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -2959,15 +2959,12 @@ Rows_log_event::Rows_log_event(const uchar *buf, uint event_len,
uint8 const common_header_len= description_event->common_header_len;
Log_event_type event_type= (Log_event_type)(uchar)buf[EVENT_TYPE_OFFSET];
m_type= event_type;
- m_cols_ai.bitmap= 0;
+ m_cols_ai.bitmap= 0; // Set to invalid, so it can be processed in is_valid().
uint8 const post_header_len= description_event->post_header_len[event_type-1];
if (event_len < (uint)(common_header_len + post_header_len))
- {
- m_cols.bitmap= 0;
DBUG_VOID_RETURN;
- }
DBUG_PRINT("enter",("event_len: %u common_header_len: %d "
"post_header_len: %d",
@@ -3076,8 +3073,6 @@ Rows_log_event::Rows_log_event(const uchar *buf, uint event_len,
DBUG_VOID_RETURN;
}
- m_cols_ai.bitmap= m_cols.bitmap; /* See explanation in is_valid() */
-
if (LOG_EVENT_IS_UPDATE_ROW(event_type))
{
DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
@@ -3096,11 +3091,21 @@ Rows_log_event::Rows_log_event(const uchar *buf, uint event_len,
}
else
{
- // Needed because my_bitmap_init() does not set it to null on failure
- m_cols_ai.bitmap= 0;
+ DBUG_ASSERT(m_cols_ai.bitmap == NULL);
DBUG_VOID_RETURN;
}
}
+ else
+ {
+ m_cols_ai= m_cols; /* Safety */
+#ifdef DBUG_OFF
+ /*
+ m_cols_ai should only be usable for update events. Make sure nobody
+ successfully manipulates it in debug builds.
+ */
+ m_cols_ai.bitmap= (my_bitmap_map*)1;
+#endif
+ }
const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc
index e43b449e6f6..dbcb0f55aae 100644
--- a/sql/log_event_server.cc
+++ b/sql/log_event_server.cc
@@ -5038,7 +5038,8 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
else
{
bitmap_intersect(table->read_set,&m_cols);
- bitmap_intersect(table->write_set, &m_cols_ai);
+ if (get_general_type_code() == UPDATE_ROWS_EVENT)
+ bitmap_intersect(table->write_set, &m_cols_ai);
table->mark_columns_per_binlog_row_image();
if (table->vfield)
table->mark_virtual_columns_for_write(0);