summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2022-06-24 11:55:42 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2022-06-24 15:37:25 +0200
commit3f9e6c9c1115179a6551fcca9c4b46da1b7954b8 (patch)
tree9608c790e8141167da671e9eb8701e2b52699d60
parent5feb60ce186a41ba97f4c9dc4ab23bab4e87296e (diff)
downloadmariadb-git-bb-10.3-MDEV-22133.tar.gz
MDEV-22133 handle_fatal_signal (sig=11) on optimized builds in handle_grant_table instead of ERROR | Buffer overflow (on optimized builds)bb-10.3-MDEV-22133
Return an error if we can not read a table required for ACL.
-rw-r--r--mysql-test/main/grant.result1
-rw-r--r--mysql-test/main/grant.test1
-rw-r--r--mysql-test/main/grant_missing.result103
-rw-r--r--mysql-test/main/grant_missing.test116
-rw-r--r--sql/sql_acl.cc96
5 files changed, 274 insertions, 43 deletions
diff --git a/mysql-test/main/grant.result b/mysql-test/main/grant.result
index 3dd1b393043..64201c6d4c5 100644
--- a/mysql-test/main/grant.result
+++ b/mysql-test/main/grant.result
@@ -1756,6 +1756,7 @@ disconnect user1;
drop database mysqltest;
use test;
call mtr.add_suppression("Can't open and lock privilege tables");
+call mtr.add_suppression("Missing system table mysql.procs_priv");
FLUSH PRIVILEGES without procs_priv table.
RENAME TABLE mysql.procs_priv TO mysql.procs_gone;
FLUSH PRIVILEGES;
diff --git a/mysql-test/main/grant.test b/mysql-test/main/grant.test
index 3279f2b381d..fb80a900188 100644
--- a/mysql-test/main/grant.test
+++ b/mysql-test/main/grant.test
@@ -1594,6 +1594,7 @@ use test;
#
call mtr.add_suppression("Can't open and lock privilege tables");
+call mtr.add_suppression("Missing system table mysql.procs_priv");
--echo FLUSH PRIVILEGES without procs_priv table.
RENAME TABLE mysql.procs_priv TO mysql.procs_gone;
diff --git a/mysql-test/main/grant_missing.result b/mysql-test/main/grant_missing.result
new file mode 100644
index 00000000000..28401d35cdd
--- /dev/null
+++ b/mysql-test/main/grant_missing.result
@@ -0,0 +1,103 @@
+#
+# MDEV-22133: handle_fatal_signal (sig=11) on optimized builds in
+# handle_grant_table instead of ERROR | Buffer overflow
+# (on optimized builds)
+#
+call mtr.add_suppression("Missing system table mysql.pro");
+call mtr.add_suppression("Missing system table mysql.roles_mapping");
+call mtr.add_suppression("Can't open and lock privilege tables");
+create user b@localhost;
+create table t(a int);
+create procedure p() select 1;
+grant EXECUTE on PROCEDURE test.p to b@localhost;
+GRANT PROXY ON 'root'@'%' TO b@localhost;
+grant SELECT(a) on test.t to b@localhost;
+grant DELETE on test.t to b@localhost;
+grant UPDATE on test.* to b@localhost;
+RENAME TABLE mysql.procs_priv TO mysql.procs_gone;
+CREATE USER a@localhost;
+drop user a@localhost;
+revoke EXECUTE on PROCEDURE test.p from b@localhost;
+ERROR 42S02: Table 'mysql.procs_priv' doesn't exist
+grant EXECUTE on PROCEDURE test.p to b@localhost;
+ERROR 42S02: Table 'mysql.procs_priv' doesn't exist
+flush privileges;
+RENAME TABLE mysql.procs_gone TO mysql.procs_priv;
+flush privileges;
+rename table mysql.proxies_priv to mysql.proxies_gone;
+CREATE USER a@localhost;
+drop user a@localhost;
+REVOKE PROXY ON 'root'@'%' FROM b@localhost;
+ERROR 42S02: Table 'mysql.proxies_priv' doesn't exist
+GRANT PROXY ON 'root'@'%' TO b@localhost;
+ERROR 42S02: Table 'mysql.proxies_priv' doesn't exist
+flush privileges;
+rename table mysql.proxies_gone to mysql.proxies_priv;
+flush privileges;
+rename table mysql.columns_priv to mysql.columns_gone;
+CREATE USER a@localhost;
+ERROR 42S02: Table 'mysql.columns_priv' doesn't exist
+drop user a@localhost;
+ERROR 42S02: Table 'mysql.columns_priv' doesn't exist
+revoke SELECT(a) on test.t from b@localhost;
+ERROR 42S02: Table 'mysql.columns_priv' doesn't exist
+grant SELECT(a) on test.t to b@localhost;
+ERROR 42S02: Table 'mysql.columns_priv' doesn't exist
+flush privileges;
+ERROR 42S02: Table 'mysql.columns_priv' doesn't exist
+rename table mysql.columns_gone to mysql.columns_priv;
+flush privileges;
+rename table mysql.tables_priv to mysql.tables_gone;
+CREATE USER a@localhost;
+ERROR 42S02: Table 'mysql.tables_priv' doesn't exist
+drop user a@localhost;
+ERROR 42S02: Table 'mysql.tables_priv' doesn't exist
+revoke DELETE on test.t from b@localhost;
+ERROR 42S02: Table 'mysql.tables_priv' doesn't exist
+grant DELETE on test.t to b@localhost;
+ERROR 42S02: Table 'mysql.tables_priv' doesn't exist
+flush privileges;
+ERROR 42S02: Table 'mysql.tables_priv' doesn't exist
+rename table mysql.tables_gone to mysql.tables_priv;
+flush privileges;
+rename table mysql.db to mysql.db_gone;
+CREATE USER a@localhost;
+ERROR 42S02: Table 'mysql.db' doesn't exist
+drop user a@localhost;
+ERROR 42S02: Table 'mysql.db' doesn't exist
+revoke UPDATE on test.* from b@localhost;
+ERROR 42S02: Table 'mysql.db' doesn't exist
+grant UPDATE on test.* to b@localhost;
+ERROR 42S02: Table 'mysql.db' doesn't exist
+flush privileges;
+ERROR 42S02: Table 'mysql.db' doesn't exist
+rename table mysql.db_gone to mysql.db;
+flush privileges;
+# Host table silently ignored bacause it can be absent in MySQL
+rename table mysql.host to mysql.host_gone;
+CREATE USER a@localhost;
+drop user a@localhost;
+flush privileges;
+rename table mysql.host_gone to mysql.host;
+flush privileges;
+rename table mysql.roles_mapping to mysql.roles_mapping_gone;
+CREATE USER a@localhost;
+drop user a@localhost;
+flush privileges;
+rename table mysql.roles_mapping_gone to mysql.roles_mapping;
+flush privileges;
+rename table mysql.user to mysql.user_gone;
+CREATE USER a@localhost;
+ERROR 42S02: Table 'mysql.user' doesn't exist
+drop user a@localhost;
+ERROR 42S02: Table 'mysql.user' doesn't exist
+flush privileges;
+ERROR 42S02: Table 'mysql.user' doesn't exist
+rename table mysql.user_gone to mysql.user;
+flush privileges;
+drop user b@localhost;
+drop table t;
+drop procedure p;
+#
+# End of 10.3 tests
+#
diff --git a/mysql-test/main/grant_missing.test b/mysql-test/main/grant_missing.test
new file mode 100644
index 00000000000..c62f7f43e11
--- /dev/null
+++ b/mysql-test/main/grant_missing.test
@@ -0,0 +1,116 @@
+
+--echo #
+--echo # MDEV-22133: handle_fatal_signal (sig=11) on optimized builds in
+--echo # handle_grant_table instead of ERROR | Buffer overflow
+--echo # (on optimized builds)
+--echo #
+
+call mtr.add_suppression("Missing system table mysql.pro");
+call mtr.add_suppression("Missing system table mysql.roles_mapping");
+call mtr.add_suppression("Can't open and lock privilege tables");
+
+create user b@localhost;
+create table t(a int);
+create procedure p() select 1;
+grant EXECUTE on PROCEDURE test.p to b@localhost;
+GRANT PROXY ON 'root'@'%' TO b@localhost;
+grant SELECT(a) on test.t to b@localhost;
+grant DELETE on test.t to b@localhost;
+grant UPDATE on test.* to b@localhost;
+
+RENAME TABLE mysql.procs_priv TO mysql.procs_gone;
+CREATE USER a@localhost;
+drop user a@localhost;
+--error ER_NO_SUCH_TABLE
+revoke EXECUTE on PROCEDURE test.p from b@localhost;
+--error ER_NO_SUCH_TABLE
+grant EXECUTE on PROCEDURE test.p to b@localhost;
+flush privileges;
+RENAME TABLE mysql.procs_gone TO mysql.procs_priv;
+flush privileges;
+
+rename table mysql.proxies_priv to mysql.proxies_gone;
+CREATE USER a@localhost;
+drop user a@localhost;
+--error ER_NO_SUCH_TABLE
+REVOKE PROXY ON 'root'@'%' FROM b@localhost;
+--error ER_NO_SUCH_TABLE
+GRANT PROXY ON 'root'@'%' TO b@localhost;
+flush privileges;
+rename table mysql.proxies_gone to mysql.proxies_priv;
+flush privileges;
+
+rename table mysql.columns_priv to mysql.columns_gone;
+--error ER_NO_SUCH_TABLE
+CREATE USER a@localhost;
+--error ER_NO_SUCH_TABLE
+drop user a@localhost;
+--error ER_NO_SUCH_TABLE
+revoke SELECT(a) on test.t from b@localhost;
+--error ER_NO_SUCH_TABLE
+grant SELECT(a) on test.t to b@localhost;
+--error ER_NO_SUCH_TABLE
+flush privileges;
+rename table mysql.columns_gone to mysql.columns_priv;
+flush privileges;
+
+rename table mysql.tables_priv to mysql.tables_gone;
+--error ER_NO_SUCH_TABLE
+CREATE USER a@localhost;
+--error ER_NO_SUCH_TABLE
+drop user a@localhost;
+--error ER_NO_SUCH_TABLE
+revoke DELETE on test.t from b@localhost;
+--error ER_NO_SUCH_TABLE
+grant DELETE on test.t to b@localhost;
+--error ER_NO_SUCH_TABLE
+flush privileges;
+rename table mysql.tables_gone to mysql.tables_priv;
+flush privileges;
+
+rename table mysql.db to mysql.db_gone;
+--error ER_NO_SUCH_TABLE
+CREATE USER a@localhost;
+--error ER_NO_SUCH_TABLE
+drop user a@localhost;
+--error ER_NO_SUCH_TABLE
+revoke UPDATE on test.* from b@localhost;
+--error ER_NO_SUCH_TABLE
+grant UPDATE on test.* to b@localhost;
+--error ER_NO_SUCH_TABLE
+flush privileges;
+rename table mysql.db_gone to mysql.db;
+flush privileges;
+
+--echo # Host table silently ignored bacause it can be absent in MySQL
+rename table mysql.host to mysql.host_gone;
+CREATE USER a@localhost;
+drop user a@localhost;
+flush privileges;
+rename table mysql.host_gone to mysql.host;
+flush privileges;
+
+rename table mysql.roles_mapping to mysql.roles_mapping_gone;
+CREATE USER a@localhost;
+drop user a@localhost;
+flush privileges;
+rename table mysql.roles_mapping_gone to mysql.roles_mapping;
+flush privileges;
+
+rename table mysql.user to mysql.user_gone;
+--error ER_NO_SUCH_TABLE
+CREATE USER a@localhost;
+--error ER_NO_SUCH_TABLE
+drop user a@localhost;
+--error ER_NO_SUCH_TABLE
+flush privileges;
+rename table mysql.user_gone to mysql.user;
+flush privileges;
+
+drop user b@localhost;
+drop table t;
+drop procedure p;
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 4c68b4505a4..38d2e9c35a1 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1036,7 +1036,7 @@ class Tables_priv_table: public Grant_table_base
Tables_priv_table() {};
- void init(enum thr_lock_type lock_type, Grant_table_base *next_table= NULL)
+ void init(enum thr_lock_type lock_type)
{
/* We are relying on init_one_table zeroing out the TABLE_LIST structure. */
LEX_CSTRING MYSQL_TABLES_PRIV_NAME={STRING_WITH_LEN("tables_priv") };
@@ -7420,6 +7420,11 @@ static bool grant_load(THD *thd,
while (!p_table->file->ha_index_next(p_table->record[0]));
}
}
+ else
+ {
+ sql_print_error("Missing system table mysql.procs_priv; "
+ "please run mysql_upgrade to create it");
+ }
end_unlock_p:
if (p_table)
@@ -10041,52 +10046,57 @@ static int handle_grant_data(THD *thd, Grant_tables& tables, bool drop,
}
/* Handle stored routines table. */
- if ((found= handle_grant_table(thd, tables.procs_priv_table(),
- PROCS_PRIV_TABLE, drop,
- user_from, user_to)) < 0)
- {
- /* Handle of table failed, don't touch in-memory array. */
- result= -1;
- }
- else
+ if (tables.procs_priv_table().table_exists())
{
- /* Handle procs array. */
- if ((handle_grant_struct(PROC_PRIVILEGES_HASH, drop, user_from, user_to) || found)
- && ! result)
- {
- result= 1; /* At least one record/element found. */
- /* If search is requested, we do not need to search further. */
- if (search_only)
- goto end;
- }
- /* Handle funcs array. */
- if ((handle_grant_struct(FUNC_PRIVILEGES_HASH, drop, user_from, user_to) || found)
- && ! result)
- {
- result= 1; /* At least one record/element found. */
- /* If search is requested, we do not need to search further. */
- if (search_only)
- goto end;
- }
- /* Handle package spec array. */
- if ((handle_grant_struct(PACKAGE_SPEC_PRIVILEGES_HASH,
- drop, user_from, user_to) || found)
- && ! result)
+ if ((found= handle_grant_table(thd, tables.procs_priv_table(),
+ PROCS_PRIV_TABLE, drop,
+ user_from, user_to)) < 0)
{
- result= 1; /* At least one record/element found. */
- /* If search is requested, we do not need to search further. */
- if (search_only)
- goto end;
+ /* Handle of table failed, don't touch in-memory array. */
+ result= -1;
}
- /* Handle package body array. */
- if ((handle_grant_struct(PACKAGE_BODY_PRIVILEGES_HASH,
- drop, user_from, user_to) || found)
- && ! result)
+ else
{
- result= 1; /* At least one record/element found. */
- /* If search is requested, we do not need to search further. */
- if (search_only)
- goto end;
+ /* Handle procs array. */
+ if ((handle_grant_struct(PROC_PRIVILEGES_HASH,
+ drop, user_from, user_to) || found)
+ && ! result)
+ {
+ result= 1; /* At least one record/element found. */
+ /* If search is requested, we do not need to search further. */
+ if (search_only)
+ goto end;
+ }
+ /* Handle funcs array. */
+ if ((handle_grant_struct(FUNC_PRIVILEGES_HASH, drop,
+ user_from, user_to) || found)
+ && ! result)
+ {
+ result= 1; /* At least one record/element found. */
+ /* If search is requested, we do not need to search further. */
+ if (search_only)
+ goto end;
+ }
+ /* Handle package spec array. */
+ if ((handle_grant_struct(PACKAGE_SPEC_PRIVILEGES_HASH,
+ drop, user_from, user_to) || found)
+ && ! result)
+ {
+ result= 1; /* At least one record/element found. */
+ /* If search is requested, we do not need to search further. */
+ if (search_only)
+ goto end;
+ }
+ /* Handle package body array. */
+ if ((handle_grant_struct(PACKAGE_BODY_PRIVILEGES_HASH,
+ drop, user_from, user_to) || found)
+ && ! result)
+ {
+ result= 1; /* At least one record/element found. */
+ /* If search is requested, we do not need to search further. */
+ if (search_only)
+ goto end;
+ }
}
}