diff --git a/mysql-test/main/grant4.result b/mysql-test/main/grant4.result index f252a4c2ad5..29021b608aa 100644 --- a/mysql-test/main/grant4.result +++ b/mysql-test/main/grant4.result @@ -148,7 +148,7 @@ call mtr.add_suppression('mysql.user table is damaged'); rename table mysql.user to mysql.user1; create table mysql.user (Host char(100), User char(100)); flush privileges; -ERROR HY000: Unknown error +ERROR HY000: Fatal error: mysql.user table is damaged or in unsupported 3.20 format drop table mysql.user; rename table mysql.user1 to mysql.user; # switching back from mysql.user to mysql.global_priv diff --git a/mysql-test/main/grant5.result b/mysql-test/main/grant5.result index df09b1fcc64..2cc1c11f7d8 100644 --- a/mysql-test/main/grant5.result +++ b/mysql-test/main/grant5.result @@ -242,4 +242,10 @@ disconnect con1; connection default; drop database db; drop user foo; +call mtr.add_suppression('mysql.host table is damaged'); +create table mysql.host (c1 int); +insert mysql.host values (1); +flush privileges; +ERROR HY000: Fatal error: mysql.host table is damaged or in unsupported 3.20 format +drop table mysql.host; # End of 10.4 tests diff --git a/mysql-test/main/grant5.test b/mysql-test/main/grant5.test index 39fcff92435..054b16c0a6e 100644 --- a/mysql-test/main/grant5.test +++ b/mysql-test/main/grant5.test @@ -199,4 +199,14 @@ delete from db.t1 returning *; drop database db; drop user foo; +# +# MDEV-23009 SIGSEGV in get_field from acl_load (on optimized builds) +# +call mtr.add_suppression('mysql.host table is damaged'); +create table mysql.host (c1 int); +insert mysql.host values (1); +--error ER_UNKNOWN_ERROR +flush privileges; +drop table mysql.host; + --echo # End of 10.4 tests diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 8e17958a8a1..11238fd573d 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -790,6 +790,15 @@ class Grant_table_base bool init_read_record(READ_RECORD* info) const { DBUG_ASSERT(m_table); + + if (num_fields() < min_columns) + { + my_printf_error(ER_UNKNOWN_ERROR, "Fatal error: mysql.%s table is " + "damaged or in unsupported 3.20 format", + MYF(ME_ERROR_LOG), m_table->s->table_name.str); + return 1; + } + bool result= ::init_read_record(info, m_table->in_use, m_table, NULL, NULL, 1, true, false); if (!result) @@ -814,7 +823,7 @@ class Grant_table_base protected: friend class Grant_tables; - Grant_table_base() : start_priv_columns(0), end_priv_columns(0), m_table(0) + Grant_table_base() : min_columns(3), start_priv_columns(0), end_priv_columns(0), m_table(0) { } /* Compute how many privilege columns this table has. This method @@ -843,6 +852,9 @@ class Grant_table_base } } + + /* the min number of columns a table should have */ + uint min_columns; /* The index at which privilege columns start. */ uint start_priv_columns; /* The index after the last privilege column */ @@ -1241,7 +1253,7 @@ class User_table_tabular: public User_table friend class Grant_tables; /* Only Grant_tables can instantiate this class. */ - User_table_tabular() {} + User_table_tabular() { min_columns= 13; /* As in 3.20.13 */ } /* The user table is a bit different compared to the other Grant tables. Usually, we only add columns to the grant tables when adding functionality. @@ -1263,13 +1275,6 @@ class User_table_tabular: public User_table int setup_sysvars() const { - if (num_fields() < 13) // number of columns in 3.21 - { - sql_print_error("Fatal error: mysql.user table is damaged or in " - "unsupported 3.20 format."); - return 1; - } - username_char_length= MY_MIN(m_table->field[1]->char_length(), USERNAME_CHAR_LENGTH); using_global_priv_table= false; @@ -1701,7 +1706,7 @@ class Db_table: public Grant_table_base private: friend class Grant_tables; - Db_table() {} + Db_table() { min_columns= 9; /* as in 3.20.13 */ } }; class Tables_priv_table: public Grant_table_base @@ -1719,7 +1724,7 @@ class Tables_priv_table: public Grant_table_base private: friend class Grant_tables; - Tables_priv_table() {} + Tables_priv_table() { min_columns= 8; /* as in 3.22.26a */ } }; class Columns_priv_table: public Grant_table_base @@ -1736,7 +1741,7 @@ class Columns_priv_table: public Grant_table_base private: friend class Grant_tables; - Columns_priv_table() {} + Columns_priv_table() { min_columns= 7; /* as in 3.22.26a */ } }; class Host_table: public Grant_table_base @@ -1748,7 +1753,7 @@ class Host_table: public Grant_table_base private: friend class Grant_tables; - Host_table() {} + Host_table() { min_columns= 8; /* as in 3.20.13 */ } }; class Procs_priv_table: public Grant_table_base @@ -1766,7 +1771,7 @@ class Procs_priv_table: public Grant_table_base private: friend class Grant_tables; - Procs_priv_table() {} + Procs_priv_table() { min_columns=8; } }; class Proxies_priv_table: public Grant_table_base @@ -1783,7 +1788,7 @@ class Proxies_priv_table: public Grant_table_base private: friend class Grant_tables; - Proxies_priv_table() {} + Proxies_priv_table() { min_columns= 7; } }; class Roles_mapping_table: public Grant_table_base @@ -1797,7 +1802,7 @@ class Roles_mapping_table: public Grant_table_base private: friend class Grant_tables; - Roles_mapping_table() {} + Roles_mapping_table() { min_columns= 4; } }; /**