summaryrefslogtreecommitdiff
path: root/sql/sql_cte.cc
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2020-12-17 10:09:16 -0800
committerIgor Babaev <igor@askmonty.org>2020-12-17 13:44:06 -0800
commit25d6f634b89c4b1ad8ae721921b5ccf595073270 (patch)
tree805021dce7c6fbcea2ee3fb6b42e211f5ee943eb /sql/sql_cte.cc
parent2cb5fb6019f4ea10106d9059307b2dbf9b9605e8 (diff)
downloadmariadb-git-25d6f634b89c4b1ad8ae721921b5ccf595073270.tar.gz
MDEV-20751 Permission Issue With Nested CTEs
Due to this bug the server reported bogus messages about lack of SELECT privileges for base tables used in the specifications of CTE tables. It happened only if such a CTE were referred to at least twice. For any non-recursive reference to CTE that is not primary the specification of the CTE is cloned. The function check_table_access() is called for such reference. The function checks privileges of the tables referenced in the specification. As no name resolution was performed for CTE references whose definitions occurred outside the specification before the call of check_table_access() that was supposed to check the access rights of the underlying tables these references were considered as references to base tables rather than references to CTEs. Yet for CTEs as well as for derived tables no privileges are needed and thus cannot be granted. The patch ensures proper name resolution of all references to CTEs before any acl checks. Approved by Oleksandr Byelkin <sanja@mariadb.com>
Diffstat (limited to 'sql/sql_cte.cc')
-rw-r--r--sql/sql_cte.cc18
1 files changed, 16 insertions, 2 deletions
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index dd764dad7cf..e07a525f691 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -864,8 +864,6 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
goto err;
spec_tables_tail= tbl;
}
- if (check_table_access(thd, SELECT_ACL, spec_tables, FALSE, UINT_MAX, FALSE))
- goto err;
if (spec_tables)
{
if (with_table->next_global)
@@ -891,6 +889,22 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
with_select));
if (check_dependencies_in_with_clauses(lex->with_clauses_list))
res= NULL;
+ /*
+ Resolve references to CTE from the spec_tables list that has not
+ been resolved yet.
+ */
+ for (TABLE_LIST *tbl= spec_tables;
+ tbl;
+ tbl= tbl->next_global)
+ {
+ if (!tbl->with)
+ tbl->with= with_select->find_table_def_in_with_clauses(tbl);
+ if (tbl == spec_tables_tail)
+ break;
+ }
+ if (check_table_access(thd, SELECT_ACL, spec_tables, FALSE, UINT_MAX, FALSE))
+ goto err;
+
lex->sphead= NULL; // in order not to delete lex->sphead
lex_end(lex);
err: