diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2018-05-07 13:49:14 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2018-05-07 13:49:14 +0300 |
commit | 648cf7176cc95f697abd8b94e860c74768680298 (patch) | |
tree | 8f3d19e0f1bd607cb515111f106715f9a4e6fcec /sql/log_event.cc | |
parent | 7b115181987fb88b97ef6d3d88bb16bdbc281e40 (diff) | |
parent | 1ecd68d867ced1d00ebffdcedbf6bc97493f5067 (diff) | |
download | mariadb-git-648cf7176cc95f697abd8b94e860c74768680298.tar.gz |
Merge remote-tracking branch 'origin/5.5-galera' into 10.0-galera
Diffstat (limited to 'sql/log_event.cc')
-rw-r--r-- | sql/log_event.cc | 69 |
1 files changed, 64 insertions, 5 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc index c57331df807..e799f37ddae 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2009, 2016, MariaDB + Copyright (c) 2000, 2018, Oracle and/or its affiliates. + Copyright (c) 2009, 2018, MariaDB 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 @@ -3674,6 +3674,25 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, db= (char *)start; query= (char *)(start + db_len + 1); q_len= data_len - db_len -1; + + if (data_len && (data_len < db_len || + data_len < q_len || + data_len != (db_len + q_len + 1))) + { + q_len= 0; + query= NULL; + DBUG_VOID_RETURN; + } + + unsigned int max_length; + max_length= (event_len - ((const char*)(end + db_len + 1) - + (buf - common_header_len))); + if (q_len != max_length) + { + q_len= 0; + query= NULL; + DBUG_VOID_RETURN; + } /** Append the db length at the end of the buffer. This will be used by Query_cache::send_result_to_client() in case the query cache is On. @@ -4144,6 +4163,20 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, you. */ thd->catalog= catalog_len ? (char *) catalog : (char *)""; + + int len_error; + size_t valid_len= system_charset_info->cset->well_formed_len(system_charset_info, + db, db + db_len, db_len, &len_error); + + if (valid_len != db_len) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid database name in Query event."); + thd->is_slave_error= true; + goto end; + } + new_db.length= db_len; new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length); thd->set_db(new_db.str, new_db.length); /* allocates a copy of 'db' */ @@ -4314,7 +4347,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, } else thd->variables.collation_database= thd->db_charset; - + /* Record any GTID in the same transaction, so slave state is transactionally consistent. @@ -4860,7 +4893,13 @@ int Start_log_event_v3::do_apply_event(rpl_group_info *rgi) */ break; default: - /* this case is impossible */ + /* + This case is not expected. It can be either an event corruption or an + unsupported binary log version. + */ + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Binlog version not supported"); DBUG_RETURN(1); } DBUG_RETURN(error); @@ -5698,6 +5737,9 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len, fields = (char*)field_lens + num_fields; table_name = fields + field_block_len; + if (strlen(table_name) > NAME_LEN) + goto err; + db = table_name + table_name_len + 1; DBUG_EXECUTE_IF ("simulate_invalid_address", db_len = data_len;); @@ -7647,6 +7689,13 @@ User_var_log_event(const char* buf, uint event_len, buf+= description_event->common_header_len + description_event->post_header_len[USER_VAR_EVENT-1]; name_len= uint4korr(buf); + /* Avoid reading out of buffer */ + if ((buf - buf_start) + UV_NAME_LEN_SIZE + name_len > event_len) + { + error= true; + goto err; + } + name= (char *) buf + UV_NAME_LEN_SIZE; /* @@ -7704,6 +7753,11 @@ User_var_log_event(const char* buf, uint event_len, we keep the flags set to UNDEF_F. */ uint bytes_read= ((val + val_len) - buf_start); + if (bytes_read > event_len) + { + error= true; + goto err; + } if ((data_written - bytes_read) > 0) { flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + @@ -9513,7 +9567,12 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len, const uchar* const ptr_rows_data= (const uchar*) ptr_after_width; - size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf); + size_t const read_size= ptr_rows_data - (const unsigned char *) buf; + if (read_size > event_len) + { + DBUG_VOID_RETURN; + } + size_t const data_size= event_len - read_size; DBUG_PRINT("info",("m_table_id: %lu m_flags: %d m_width: %lu data_size: %lu", m_table_id, m_flags, m_width, (ulong) data_size)); |