diff options
author | Nikita Malyavin <nikitamalyavin@gmail.com> | 2023-04-11 00:11:21 +0300 |
---|---|---|
committer | Nikita Malyavin <nikitamalyavin@gmail.com> | 2023-05-06 00:00:27 +0300 |
commit | 47f5c7ae7e452225bd8f0f3c88ca1b5be36c85a7 (patch) | |
tree | 27f7e524afa8f39409f35a297f452962ffeb4202 | |
parent | a50bcc2a70037bfe78b7d582d7051159899e868c (diff) | |
download | mariadb-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.cc | 21 | ||||
-rw-r--r-- | sql/log_event_server.cc | 3 |
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); |