Commit 78f09b12 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-23009 SIGSEGV in get_field from acl_load (on optimized builds)

Classes that handle privilege tables (like Tables_priv_table)
could read some columns conditionally but they expect a certain
minimal number of colunms always to exist.

Add a check for a minimal required number of columns in privilege tables,
don't use a table that has fewer columns than required.
parent a874b6c4
...@@ -148,7 +148,7 @@ call mtr.add_suppression('mysql.user table is damaged'); ...@@ -148,7 +148,7 @@ call mtr.add_suppression('mysql.user table is damaged');
rename table mysql.user to mysql.user1; rename table mysql.user to mysql.user1;
create table mysql.user (Host char(100), User char(100)); create table mysql.user (Host char(100), User char(100));
flush privileges; 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; drop table mysql.user;
rename table mysql.user1 to mysql.user; rename table mysql.user1 to mysql.user;
# switching back from mysql.user to mysql.global_priv # switching back from mysql.user to mysql.global_priv
......
...@@ -242,4 +242,10 @@ disconnect con1; ...@@ -242,4 +242,10 @@ disconnect con1;
connection default; connection default;
drop database db; drop database db;
drop user foo; 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 # End of 10.4 tests
...@@ -199,4 +199,14 @@ delete from db.t1 returning *; ...@@ -199,4 +199,14 @@ delete from db.t1 returning *;
drop database db; drop database db;
drop user foo; 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 --echo # End of 10.4 tests
...@@ -790,6 +790,15 @@ class Grant_table_base ...@@ -790,6 +790,15 @@ class Grant_table_base
bool init_read_record(READ_RECORD* info) const bool init_read_record(READ_RECORD* info) const
{ {
DBUG_ASSERT(m_table); 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, bool result= ::init_read_record(info, m_table->in_use, m_table,
NULL, NULL, 1, true, false); NULL, NULL, 1, true, false);
if (!result) if (!result)
...@@ -814,7 +823,7 @@ class Grant_table_base ...@@ -814,7 +823,7 @@ class Grant_table_base
protected: protected:
friend class Grant_tables; 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 /* Compute how many privilege columns this table has. This method
...@@ -843,6 +852,9 @@ class Grant_table_base ...@@ -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. */ /* The index at which privilege columns start. */
uint start_priv_columns; uint start_priv_columns;
/* The index after the last privilege column */ /* The index after the last privilege column */
...@@ -1241,7 +1253,7 @@ class User_table_tabular: public User_table ...@@ -1241,7 +1253,7 @@ class User_table_tabular: public User_table
friend class Grant_tables; friend class Grant_tables;
/* Only Grant_tables can instantiate this class. */ /* 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. /* 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. Usually, we only add columns to the grant tables when adding functionality.
...@@ -1263,13 +1275,6 @@ class User_table_tabular: public User_table ...@@ -1263,13 +1275,6 @@ class User_table_tabular: public User_table
int setup_sysvars() const 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= MY_MIN(m_table->field[1]->char_length(),
USERNAME_CHAR_LENGTH); USERNAME_CHAR_LENGTH);
using_global_priv_table= false; using_global_priv_table= false;
...@@ -1701,7 +1706,7 @@ class Db_table: public Grant_table_base ...@@ -1701,7 +1706,7 @@ class Db_table: public Grant_table_base
private: private:
friend class Grant_tables; friend class Grant_tables;
Db_table() {} Db_table() { min_columns= 9; /* as in 3.20.13 */ }
}; };
class Tables_priv_table: public Grant_table_base class Tables_priv_table: public Grant_table_base
...@@ -1719,7 +1724,7 @@ class Tables_priv_table: public Grant_table_base ...@@ -1719,7 +1724,7 @@ class Tables_priv_table: public Grant_table_base
private: private:
friend class Grant_tables; 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 class Columns_priv_table: public Grant_table_base
...@@ -1736,7 +1741,7 @@ class Columns_priv_table: public Grant_table_base ...@@ -1736,7 +1741,7 @@ class Columns_priv_table: public Grant_table_base
private: private:
friend class Grant_tables; 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 class Host_table: public Grant_table_base
...@@ -1748,7 +1753,7 @@ class Host_table: public Grant_table_base ...@@ -1748,7 +1753,7 @@ class Host_table: public Grant_table_base
private: private:
friend class Grant_tables; friend class Grant_tables;
Host_table() {} Host_table() { min_columns= 8; /* as in 3.20.13 */ }
}; };
class Procs_priv_table: public Grant_table_base class Procs_priv_table: public Grant_table_base
...@@ -1766,7 +1771,7 @@ class Procs_priv_table: public Grant_table_base ...@@ -1766,7 +1771,7 @@ class Procs_priv_table: public Grant_table_base
private: private:
friend class Grant_tables; friend class Grant_tables;
Procs_priv_table() {} Procs_priv_table() { min_columns=8; }
}; };
class Proxies_priv_table: public Grant_table_base class Proxies_priv_table: public Grant_table_base
...@@ -1783,7 +1788,7 @@ class Proxies_priv_table: public Grant_table_base ...@@ -1783,7 +1788,7 @@ class Proxies_priv_table: public Grant_table_base
private: private:
friend class Grant_tables; friend class Grant_tables;
Proxies_priv_table() {} Proxies_priv_table() { min_columns= 7; }
}; };
class Roles_mapping_table: public Grant_table_base class Roles_mapping_table: public Grant_table_base
...@@ -1797,7 +1802,7 @@ class Roles_mapping_table: public Grant_table_base ...@@ -1797,7 +1802,7 @@ class Roles_mapping_table: public Grant_table_base
private: private:
friend class Grant_tables; friend class Grant_tables;
Roles_mapping_table() {} Roles_mapping_table() { min_columns= 4; }
}; };
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment