diff options
-rw-r--r-- | include/mysql_com.h | 2 | ||||
-rw-r--r-- | include/sql_common.h | 2 | ||||
-rwxr-xr-x | mysql-test/mysql-test-run.pl | 2 | ||||
-rw-r--r-- | mysys/lf_hash.c | 9 | ||||
-rw-r--r-- | sql/event_db_repository.cc | 5 | ||||
-rw-r--r-- | sql/log_event.cc | 120 | ||||
-rw-r--r-- | sql/log_event_old.cc | 12 | ||||
-rw-r--r-- | sql/mysqld.cc | 2 | ||||
-rw-r--r-- | sql/sp.cc | 6 | ||||
-rw-r--r-- | sql/sql_acl.cc | 2 | ||||
-rw-r--r-- | sql/sql_admin.cc | 2 | ||||
-rw-r--r-- | sql/sql_base.h | 2 | ||||
-rw-r--r-- | sql/sql_partition.cc | 2 | ||||
-rw-r--r-- | sql/sql_plugin.cc | 14 | ||||
-rw-r--r-- | sql/sql_priv.h | 9 | ||||
-rw-r--r-- | sql/sql_table.cc | 2 | ||||
-rw-r--r-- | sql/sql_trigger.cc | 1 | ||||
-rw-r--r-- | sql/sql_truncate.cc | 3 | ||||
-rw-r--r-- | sql/table.cc | 16 | ||||
-rw-r--r-- | sql/table.h | 7 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 4 |
21 files changed, 190 insertions, 34 deletions
diff --git a/include/mysql_com.h b/include/mysql_com.h index df9681e02a4..d76dc72e2b8 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2010, 2013, Monty Program Ab + Copyright (c) 2010, 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 diff --git a/include/sql_common.h b/include/sql_common.h index a1c9faac82d..5bfe5ba8969 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -1,7 +1,7 @@ #ifndef SQL_COMMON_INCLUDED #define SQL_COMMON_INCLUDED /* Copyright (c) 2003, 2012, Oracle and/or its affiliates. - Copyright (c) 2010, 2012, Monty Program Ab + Copyright (c) 2010, 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 diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 61ad87cc21c..0f915a8777a 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2,7 +2,7 @@ # -*- cperl -*- # Copyright (c) 2004, 2014, Oracle and/or its affiliates. -# Copyright (c) 2009, 2017, MariaDB Corporation +# Copyright (c) 2009, 2018, MariaDB Corporation # # 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 diff --git a/mysys/lf_hash.c b/mysys/lf_hash.c index 797c20e819e..8d74aaf8cc2 100644 --- a/mysys/lf_hash.c +++ b/mysys/lf_hash.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2006, 2010, Oracle and/or its affiliates. - Copyright (c) 2009, 2016, MariaDB +/* Copyright (c) 2006, 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 @@ -86,7 +86,8 @@ retry: do { /* PTR() isn't necessary below, head is a dummy node */ cursor->curr= (LF_SLIST *)(*cursor->prev); _lf_pin(pins, 1, cursor->curr); - } while (*cursor->prev != (intptr)cursor->curr && LF_BACKOFF); + } while (my_atomic_loadptr((void**)cursor->prev) != cursor->curr && + LF_BACKOFF); for (;;) { if (unlikely(!cursor->curr)) @@ -100,7 +101,7 @@ retry: cur_hashnr= cursor->curr->hashnr; cur_key= cursor->curr->key; cur_keylen= cursor->curr->keylen; - if (*cursor->prev != (intptr)cursor->curr) + if (my_atomic_loadptr((void**)cursor->prev) != cursor->curr) { (void)LF_BACKOFF; goto retry; diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index 673250ffd22..481a49bf5b0 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -1,5 +1,6 @@ /* - Copyright (c) 2006, 2011, Oracle and/or its affiliates. + Copyright (c) 2006, 2017, 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 @@ -176,6 +177,8 @@ protected: error_log_print(ERROR_LEVEL, fmt, args); va_end(args); } +public: + Event_db_intact() { has_keys= TRUE; } }; /** In case of an error, a message is printed to the error log. */ diff --git a/sql/log_event.cc b/sql/log_event.cc index 18e4cfbf187..a33704bdd03 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 @@ -3333,6 +3333,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. @@ -3613,6 +3632,20 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, 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' */ @@ -3789,7 +3822,23 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, } else thd->variables.collation_database= thd->db_charset; - + + { + const CHARSET_INFO *cs= thd->charset(); + /* + We cannot ask for parsing a statement using a character set + without state_maps (parser internal data). + */ + if (!cs->state_map) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "character_set cannot be parsed"); + thd->is_slave_error= true; + goto end; + } + } + thd->table_map_for_update= (table_map)table_map_for_update; thd->set_invoker(&user, &host); /* @@ -4256,7 +4305,13 @@ int Start_log_event_v3::do_apply_event(Relay_log_info const *rli) */ 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); @@ -5182,6 +5237,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;); @@ -6378,6 +6436,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; /* @@ -6437,6 +6502,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) - 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 + @@ -6651,7 +6721,12 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) } if (!(charset= get_charset(charset_number, MYF(MY_WME)))) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid character set for User var event"); DBUG_RETURN(1); + } LEX_STRING user_var_name; user_var_name.str= name; user_var_name.length= name_len; @@ -6672,12 +6747,26 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) { switch (type) { case REAL_RESULT: + if (val_len != 8) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid variable length at User var event"); + return 1; + } float8get(real_val, val); it= new Item_float(real_val, 0); val= (char*) &real_val; // Pointer to value in native format val_len= 8; break; case INT_RESULT: + if (val_len != 8) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid variable length at User var event"); + return 1; + } int_val= (longlong) uint8korr(val); it= new Item_int(int_val); val= (char*) &int_val; // Pointer to value in native format @@ -6685,6 +6774,13 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) break; case DECIMAL_RESULT: { + if (val_len < 3) + { + rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR, + ER_THD(thd, ER_SLAVE_FATAL_ERROR), + "Invalid variable length at User var event"); + return 1; + } Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]); it= dec; val= (char *)dec->val_decimal(NULL); @@ -8124,6 +8220,15 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len, DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); m_width = net_field_length(&ptr_after_width); DBUG_PRINT("debug", ("m_width=%lu", m_width)); + /* Avoid reading out of buffer */ + if (static_cast<unsigned int>((ptr_after_width + + (m_width + 7) / 8) - + (uchar*)buf) > event_len) + { + m_cols.bitmap= NULL; + DBUG_VOID_RETURN; + } + /* if bitmap_init fails, catched in is_valid() */ if (likely(!bitmap_init(&m_cols, m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, @@ -8172,7 +8277,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)); diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index 51fcf902f77..3d54ffdf7eb 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -1,4 +1,5 @@ -/* Copyright (c) 2007, 2016, Oracle and/or its affiliates. +/* Copyright (c) 2007, 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 @@ -1357,6 +1358,15 @@ Old_rows_log_event::Old_rows_log_event(const char *buf, uint event_len, DBUG_PRINT("debug", ("Reading from %p", ptr_after_width)); m_width = net_field_length(&ptr_after_width); DBUG_PRINT("debug", ("m_width=%lu", m_width)); + /* Avoid reading out of buffer */ + if (static_cast<unsigned int>(m_width + + (ptr_after_width - + (const uchar *)buf)) > event_len) + { + m_cols.bitmap= NULL; + DBUG_VOID_RETURN; + } + /* if bitmap_init fails, catched in is_valid() */ if (likely(!bitmap_init(&m_cols, m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index c78f2ffd94f..5a9aba7f2e4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2008, 2015, SkySQL Ab. + Copyright (c) 2008, 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 diff --git a/sql/sp.cc b/sql/sp.cc index c12dcc76f27..62ed89f4a02 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2002, 2016, Oracle and/or its affiliates. - Copyright (c) 2009, 2017, MariaDB + Copyright (c) 2002, 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 @@ -354,7 +354,7 @@ private: bool m_print_once; public: - Proc_table_intact() : m_print_once(TRUE) {} + Proc_table_intact() : m_print_once(TRUE) { has_keys= TRUE; } protected: void report_error(uint code, const char *fmt, ...); diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 03f0e878db6..16358409124 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2009, 2016, MariaDB + 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 diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc index 7cddf50a896..9897e4b4302 100644 --- a/sql/sql_admin.cc +++ b/sql/sql_admin.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2010, 2015, Oracle and/or its affiliates. - Copyright (c) 2011, 2016, MariaDB + Copyright (c) 2011, 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 diff --git a/sql/sql_base.h b/sql/sql_base.h index 0cde933afb8..646e391a58b 100644 --- a/sql/sql_base.h +++ b/sql/sql_base.h @@ -1,4 +1,6 @@ /* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 2011, 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 diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 8e58c34162f..b25a3c2bcf3 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2005, 2017, Oracle and/or its affiliates. - Copyright (c) 2009, 2017, SkySQL Ab. + 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 diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index e616b0a09e4..b378cdc0fa1 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1,6 +1,6 @@ /* - Copyright (c) 2005, 2013, Oracle and/or its affiliates. - Copyright (c) 2010, 2014, SkySQL Ab. + Copyright (c) 2005, 2018, Oracle and/or its affiliates. + Copyright (c) 2010, 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 @@ -2243,6 +2243,16 @@ bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, if (! (table= open_ltable(thd, &tables, TL_WRITE, MYSQL_LOCK_IGNORE_TIMEOUT))) DBUG_RETURN(TRUE); + if (!table->key_info) + { + my_printf_error(ER_UNKNOWN_ERROR, + "The table %s.%s has no primary key. " + "Please check the table definition and " + "create the primary key accordingly.", MYF(0), + table->s->db.str, table->s->table_name.str); + DBUG_RETURN(TRUE); + } + /* Pre-acquire audit plugins for events that may potentially occur during [UN]INSTALL PLUGIN. diff --git a/sql/sql_priv.h b/sql/sql_priv.h index b5589cb4b22..3195c5bb4a4 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2014, Oracle and/or its affiliates. - Copyright (c) 2010, 2014, Monty Program Ab. +/* Copyright (c) 2000, 2018, Oracle and/or its affiliates. + Copyright (c) 2010, 2018, Monty Program Ab. 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 @@ -193,6 +193,11 @@ template <class T> T available_buffer(const char* buf_start, const char* buf_current, T buf_len) { + /* Sanity check */ + if (buf_current < buf_start || + buf_len < static_cast<T>(buf_current - buf_start)) + return static_cast<T>(0); + return buf_len - (buf_current - buf_start); } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f56781faf39..1b83b513c2d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2010, 2016, MariaDB + Copyright (c) 2010, 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 diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 4d7338b2e1d..344ebdf8407 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1,5 +1,6 @@ /* Copyright (c) 2004, 2012, Oracle and/or its affiliates. + Copyright (c) 2010, 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 diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc index 9b37996f377..ed36ab428a2 100644 --- a/sql/sql_truncate.cc +++ b/sql/sql_truncate.cc @@ -1,4 +1,5 @@ -/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2015, Oracle and/or its affiliates. + Copyright (c) 2012, 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 diff --git a/sql/table.cc b/sql/table.cc index 5d73d7dffd2..bb4eae9b1e2 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2015, Oracle and/or its affiliates. - Copyright (c) 2008, 2015, MariaDB +/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. + Copyright (c) 2008, 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 @@ -3630,7 +3630,7 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) /* Whether the table definition has already been validated. */ if (table->s->table_field_def_cache == table_def) - DBUG_RETURN(FALSE); + goto end; if (table->s->fields != table_def->count) { @@ -3753,6 +3753,16 @@ Table_check_intact::check(TABLE *table, const TABLE_FIELD_DEF *table_def) if (! error) table->s->table_field_def_cache= table_def; +end: + + if (has_keys && !error && !table->key_info) + { + report_error(0, "Incorrect definition of table %s.%s: " + "indexes are missing", + table->s->db.str, table->alias.c_ptr()); + error= TRUE; + } + DBUG_RETURN(error); } diff --git a/sql/table.h b/sql/table.h index fcf214d3582..1d4a1d9a2d2 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1,7 +1,7 @@ #ifndef TABLE_INCLUDED #define TABLE_INCLUDED -/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. - Copyright (c) 2009, 2014, SkySQL Ab. +/* Copyright (c) 2000, 2017, 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 @@ -496,10 +496,11 @@ typedef struct st_ha_data_partition class Table_check_intact { protected: + bool has_keys; virtual void report_error(uint code, const char *fmt, ...)= 0; public: - Table_check_intact() {} + Table_check_intact() : has_keys(FALSE) {} virtual ~Table_check_intact() {} /** Checks whether a table is intact. */ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 3aabfc319c6..c3bacee91ff 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2015, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. @@ -9434,8 +9434,10 @@ ha_innobase::start_stmt( case SQLCOM_INSERT: case SQLCOM_UPDATE: case SQLCOM_DELETE: + case SQLCOM_REPLACE: init_table_handle_for_HANDLER(); prebuilt->select_lock_type = LOCK_X; + prebuilt->stored_select_lock_type = LOCK_X; error = row_lock_table_for_mysql(prebuilt, NULL, 1); if (error != DB_SUCCESS) { |