ERROR 42000: SHOW command denied touser'u'@'localhost'fortable `db`.`s`
createtable t (a intnotnulldefault(nextval(s)));
insertinto t values (),();
select * from t;
a
1
2
selectdefault(a) from t;
default(a)
3
4
disconnect con1;
So, the user u does not have any access to the sequence db.s, cannot read from it or see its structure.
However, the user can refer to it in CREATE TABLE, and can read/insert a default value in such a table, thus both reading and modifying the sequence.
It has been discussed that the privileges should be checked at some point. It can be done
1) upon table creation/altering, or
2) upon insert/select.
Either way is likely to break something for existing users. Probably the first way, checking privileges upon creation, will break less, at least because this is a less frequent operation than INSERT/SELECT, but it's hard to predict for sure.
Another argument for the first approach is that the existence of the sequence is already checked upon CREATE, one can't create a table referring a sequence in DEFAULT if the sequence doesn't exist or if the referred object is not a sequence, which also means that in the variation of the test case above the unprivileged user gets information about db.s which they shouldn't normally have:
createuser u;
grantcreate, insert, selecton db.t to u;
createtable db.s (x int);
connect con1,localhost,u,,db;
createtable t (a intnotnulldefault(nextval(s)));
ERROR 42S02: 'db.s'isnot a SEQUENCE
createtable t (a intnotnulldefault(nextval(s2)));
ERROR 42S02: Table'db.s2' doesn't exist
Attachments
Issue Links
blocks
MDEV-36280ALTER TABLE require ALTER privilege on sequence from DEFAULT value expression
In Review
relates to
MDEV-19479Privileges not applied correctly for sequences when altering a column to take a default value from a sequence
Confirmed
MDEV-36380User has unauthorized access to a sequence through a view with security invoker
Also, a table referencing another table is somewhat similar to foreign keys. And for them the privilege is checked on creation, not on every check.
Sergei Golubchik
added a comment - Also, a table referencing another table is somewhat similar to foreign keys. And for them the privilege is checked on creation, not on every check.
Another argument for the "upon creation" approach is that a user doesn't need to have a privilege on a column to insert a default value into the column, so it would be strange if it required a privilege on the underlying function which generates this value.
Elena Stepanova
added a comment - Another argument for the "upon creation" approach is that a user doesn't need to have a privilege on a column to insert a default value into the column, so it would be strange if it required a privilege on the underlying function which generates this value.
Found one issue with CREATE TABLE and prepared statements, where the prepared statement changes the lex table lists in an incompatible way compared to normal execution. I have created a patch for this, but need to have the patch reviewed by Sanja as it is hard to know that it is 100% correct.
The problem can be seen by running mtr --ps sql_sequence.grant in the bb-10.11-monty2 tree. This fails because the code expects the wrong grants for the used tables.
The bug is that TABLE_LIST *LEX::unlink_first_table() and LEX::link_first_table_back() does not restore back the original table lists because of the call to first_lists_tables_same() in unlink_first_table() which irrevocable changes the table lists.
I do not like that we have to call unlink - link_back in many places of the code, just because of some statements has an indirect SELECT attached (CREATE ... SELECT, INSERT ... SELECT). It would be better that lex would keep the 'main tables' in a separate list so that we could use the SELECT part directly without ever have to modify the lists back and forth.
Michael Widenius
added a comment - - edited Found one issue with CREATE TABLE and prepared statements, where the prepared statement changes the lex table lists in an incompatible way compared to normal execution. I have created a patch for this, but need to have the patch reviewed by Sanja as it is hard to know that it is 100% correct.
The problem can be seen by running mtr --ps sql_sequence.grant in the bb-10.11-monty2 tree. This fails because the code expects the wrong grants for the used tables.
The bug is that TABLE_LIST *LEX::unlink_first_table() and LEX::link_first_table_back() does not restore back the original table lists because of the call to first_lists_tables_same() in unlink_first_table() which irrevocable changes the table lists.
I do not like that we have to call unlink - link_back in many places of the code, just because of some statements has an indirect SELECT attached (CREATE ... SELECT, INSERT ... SELECT). It would be better that lex would keep the 'main tables' in a separate list so that we could use the SELECT part directly without ever have to modify the lists back and forth.
Oleksandr Byelkin
added a comment -
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index f3d51db028d..b9c81e14ef7 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -1226,6 +1226,7 @@ void LEX::start(THD *thd_arg)
with_clauses_list_last_next= &with_clauses_list;
clone_spec_offset= 0;
create_view= NULL;
+ create_group= NULL;
field_list.empty();
value_list.empty();
update_list.empty();
@@ -4483,8 +4484,30 @@ void LEX::set_trg_event_type_for_tables()
/*
- Unlink the first table from the global table list and the first table from
- outer select (lex->select_lex) local list
+ It happens that when we parse CREATE TABLE at the first place goes
+ not only the table we are creating but also sequences used in this table
+ exprssions. This function called in the parser just after parsing the
+ table definition to mark of this group of tables
+*/
+
+void LEX::mark_create_group()
+{
+ create_group= query_tables;
+ if (query_tables)
+ {
+ while(create_group->next_global)
+ {
+ create_group= create_group->next_global;
+ // all sequences of CREATE are not linked locally
+ DBUG_ASSERT(create_group->next_local == NULL);
+ }
+ }
+}
+
+/*
+ Unlink the first table with its group (if present) from the global
+ table list and the first table from outer select (lex->select_lex)
+ local list
SYNOPSIS
unlink_first_table()
@@ -4506,13 +4529,14 @@ TABLE_LIST *LEX::unlink_first_table(bool *link_to_local)
if ((first= query_tables))
{
/*
- Exclude from global table list
+ Exclude the group from global table list (see mark_create_group)
*/
- if ((query_tables= query_tables->next_global))
+ TABLE_LIST *last= (create_group ? create_group : query_tables );
+ if ((query_tables= last->next_global))
query_tables->prev_global= &query_tables;
else
query_tables_last= &query_tables;
- first->next_global= 0;
+ last->next_global= 0;
/*
and from local list if it is not empty
@@ -4598,7 +4622,8 @@ void LEX::fix_first_select_number()
/*
- Link table back that was unlinked with unlink_first_table()
+ Link back ex-first table with its group that was unlinked with
+ unlink_first_table()
SYNOPSIS
link_first_table_back()
@@ -4613,10 +4638,12 @@ void LEX::link_first_table_back(TABLE_LIST *first,
{
if (first)
{
- if ((first->next_global= query_tables))
- query_tables->prev_global= &first->next_global;
+ // see mark_create_group for create_group explanation
+ TABLE_LIST *last= (create_group ? create_group : first);
+ if ((last->next_global= query_tables))
+ query_tables->prev_global= &last->next_global;
else
- query_tables_last= &first->next_global;
+ query_tables_last= &last->next_global;
query_tables= first;
if (link_to_local)
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 6312102e076..12affb42897 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -3230,6 +3230,7 @@ struct LEX: public Query_tables_list
my_ptrdiff_t clone_spec_offset;
Create_view_info *create_view;
+ TABLE_LIST *create_group;
/* Query Plan Footprint of a currently running select */
Explain_query *explain;
@@ -4934,6 +4935,7 @@ struct LEX: public Query_tables_list
builtin_select.options |= SELECT_DESCRIBE;
}
+ void mark_create_group();
};
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index d5aeb57d546..bd6b5467114 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -10150,9 +10150,15 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
table && table != tables ;
table= table->next_global)
{
+ DBUG_ASSERT(table->sequence);
if (check_table_access(thd, INSERT_ACL | SELECT_ACL, table,
FALSE, 1, FALSE))
goto err;
+ // after last table in group starts other tables or it is the end
+ DBUG_ASSERT((table == lex->create_group &&
+ (table->next_global == NULL ||
+ table->next_global == tables)) ||
+ table != lex->create_group);
}
if (select_lex->item_list.elements)
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 2abd0a529af..6de89f05ffb 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -4472,7 +4472,10 @@ trg_event:
create_body:
create_field_list_parens
- { Lex->create_info.option_list= NULL; }
+ {
+ Lex->create_info.option_list= NULL;
+ Lex->mark_create_group();
+ }
opt_create_table_options opt_create_partitioning opt_create_select {}
| opt_create_table_options opt_create_partitioning opt_create_select {}
| create_like
People
Sergei Golubchik
Elena Stepanova
Votes:
0Vote for this issue
Watchers:
7Start watching this issue
Dates
Created:
Updated:
Resolved:
Git Integration
Error rendering 'com.xiplink.jira.git.jira_git_plugin:git-issue-webpanel'. Please contact your Jira administrators.
{"report":{"fcp":982.1999999880791,"ttfb":280.10000002384186,"pageVisibility":"visible","entityId":133528,"key":"jira.project.issue.view-issue","isInitial":true,"threshold":1000,"elementTimings":{},"userDeviceMemory":8,"userDeviceProcessors":64,"apdex":0.5,"journeyId":"a2b92fcc-e0c9-4268-9a13-9727ef92d702","navigationType":0,"readyForUser":1077.5,"redirectCount":0,"resourceLoadedEnd":1304.800000011921,"resourceLoadedStart":284.80000001192093,"resourceTiming":[{"duration":232.69999998807907,"initiatorType":"link","name":"https://jira.mariadb.org/s/2c21342762a6a02add1c328bed317ffd-CDN/lu2bu7/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/css/_super/batch.css","startTime":284.80000001192093,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":284.80000001192093,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":517.5,"responseStart":0,"secureConnectionStart":0},{"duration":232.89999997615814,"initiatorType":"link","name":"https://jira.mariadb.org/s/7ebd35e77e471bc30ff0eba799ebc151-CDN/lu2bu7/820016/12ta74/8679b4946efa1a0bb029a3a22206fb5d/_/download/contextbatch/css/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.css?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&slack-enabled=true","startTime":285,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":285,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":517.8999999761581,"responseStart":0,"secureConnectionStart":0},{"duration":241.80000001192093,"initiatorType":"script","name":"https://jira.mariadb.org/s/fbf975c0cce4b1abf04784eeae9ba1f4-CDN/lu2bu7/820016/12ta74/0a8bac35585be7fc6c9cc5a0464cd4cf/_/download/contextbatch/js/_super/batch.js?locale=en","startTime":285.19999998807907,"connectEnd":285.19999998807907,"connectStart":285.19999998807907,"domainLookupEnd":285.19999998807907,"domainLookupStart":285.19999998807907,"fetchStart":285.19999998807907,"redirectEnd":0,"redirectStart":0,"requestStart":285.19999998807907,"responseEnd":527,"responseStart":527,"secureConnectionStart":285.19999998807907},{"duration":272.9000000357628,"initiatorType":"script","name":"https://jira.mariadb.org/s/099b33461394b8015fc36c0a4b96e19f-CDN/lu2bu7/820016/12ta74/8679b4946efa1a0bb029a3a22206fb5d/_/download/contextbatch/js/jira.browse.project,project.issue.navigator,jira.view.issue,jira.general,jira.global,atl.general,-_super/batch.js?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&locale=en&slack-enabled=true","startTime":285.39999997615814,"connectEnd":285.39999997615814,"connectStart":285.39999997615814,"domainLookupEnd":285.39999997615814,"domainLookupStart":285.39999997615814,"fetchStart":285.39999997615814,"redirectEnd":0,"redirectStart":0,"requestStart":285.39999997615814,"responseEnd":558.3000000119209,"responseStart":558.3000000119209,"secureConnectionStart":285.39999997615814},{"duration":276.69999998807907,"initiatorType":"script","name":"https://jira.mariadb.org/s/94c15bff32baef80f4096a08aceae8bc-CDN/lu2bu7/820016/12ta74/c92c0caa9a024ae85b0ebdbed7fb4bd7/_/download/contextbatch/js/atl.global,-_super/batch.js?locale=en","startTime":285.5,"connectEnd":285.5,"connectStart":285.5,"domainLookupEnd":285.5,"domainLookupStart":285.5,"fetchStart":285.5,"redirectEnd":0,"redirectStart":0,"requestStart":285.5,"responseEnd":562.1999999880791,"responseStart":562.1999999880791,"secureConnectionStart":285.5},{"duration":276.80000001192093,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bu7/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-en/jira.webresources:calendar-en.js","startTime":285.80000001192093,"connectEnd":285.80000001192093,"connectStart":285.80000001192093,"domainLookupEnd":285.80000001192093,"domainLookupStart":285.80000001192093,"fetchStart":285.80000001192093,"redirectEnd":0,"redirectStart":0,"requestStart":285.80000001192093,"responseEnd":562.6000000238419,"responseStart":562.6000000238419,"secureConnectionStart":285.80000001192093},{"duration":277.19999998807907,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bu7/820016/12ta74/1.0/_/download/batch/jira.webresources:calendar-localisation-moment/jira.webresources:calendar-localisation-moment.js","startTime":286,"connectEnd":286,"connectStart":286,"domainLookupEnd":286,"domainLookupStart":286,"fetchStart":286,"redirectEnd":0,"redirectStart":0,"requestStart":286,"responseEnd":563.1999999880791,"responseStart":563.1999999880791,"secureConnectionStart":286},{"duration":382.0999999642372,"initiatorType":"link","name":"https://jira.mariadb.org/s/b04b06a02d1959df322d9cded3aeecc1-CDN/lu2bu7/820016/12ta74/a2ff6aa845ffc9a1d22fe23d9ee791fc/_/download/contextbatch/css/jira.global.look-and-feel,-_super/batch.css","startTime":286.10000002384186,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":286.10000002384186,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":668.1999999880791,"responseStart":0,"secureConnectionStart":0},{"duration":277.80000001192093,"initiatorType":"script","name":"https://jira.mariadb.org/rest/api/1.0/shortcuts/820016/47140b6e0a9bc2e4913da06536125810/shortcuts.js?context=issuenavigation&context=issueaction","startTime":286.19999998807907,"connectEnd":286.19999998807907,"connectStart":286.19999998807907,"domainLookupEnd":286.19999998807907,"domainLookupStart":286.19999998807907,"fetchStart":286.19999998807907,"redirectEnd":0,"redirectStart":0,"requestStart":286.19999998807907,"responseEnd":564,"responseStart":564,"secureConnectionStart":286.19999998807907},{"duration":381.89999997615814,"initiatorType":"link","name":"https://jira.mariadb.org/s/3ac36323ba5e4eb0af2aa7ac7211b4bb-CDN/lu2bu7/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/css/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.css?jira.create.linked.issue=true","startTime":286.5,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":286.5,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":668.3999999761581,"responseStart":0,"secureConnectionStart":0},{"duration":278.10000002384186,"initiatorType":"script","name":"https://jira.mariadb.org/s/3339d87fa2538a859872f2df449bf8d0-CDN/lu2bu7/820016/12ta74/d176f0986478cc64f24226b3d20c140d/_/download/contextbatch/js/com.atlassian.jira.projects.sidebar.init,-_super,-project.issue.navigator,-jira.view.issue/batch.js?jira.create.linked.issue=true&locale=en","startTime":286.69999998807907,"connectEnd":286.69999998807907,"connectStart":286.69999998807907,"domainLookupEnd":286.69999998807907,"domainLookupStart":286.69999998807907,"fetchStart":286.69999998807907,"redirectEnd":0,"redirectStart":0,"requestStart":286.69999998807907,"responseEnd":564.8000000119209,"responseStart":564.8000000119209,"secureConnectionStart":286.69999998807907},{"duration":547,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bu7/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-js/jira.webresources:bigpipe-js.js","startTime":299.10000002384186,"connectEnd":299.10000002384186,"connectStart":299.10000002384186,"domainLookupEnd":299.10000002384186,"domainLookupStart":299.10000002384186,"fetchStart":299.10000002384186,"redirectEnd":0,"redirectStart":0,"requestStart":299.10000002384186,"responseEnd":846.1000000238419,"responseStart":846.1000000238419,"secureConnectionStart":299.10000002384186},{"duration":989.1000000238419,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bu7/820016/12ta74/1.0/_/download/batch/jira.webresources:bigpipe-init/jira.webresources:bigpipe-init.js","startTime":313.89999997615814,"connectEnd":313.89999997615814,"connectStart":313.89999997615814,"domainLookupEnd":313.89999997615814,"domainLookupStart":313.89999997615814,"fetchStart":313.89999997615814,"redirectEnd":0,"redirectStart":0,"requestStart":313.89999997615814,"responseEnd":1303,"responseStart":1303,"secureConnectionStart":313.89999997615814},{"duration":195.10000002384186,"initiatorType":"xmlhttprequest","name":"https://jira.mariadb.org/rest/webResources/1.0/resources","startTime":679.6999999880791,"connectEnd":679.6999999880791,"connectStart":679.6999999880791,"domainLookupEnd":679.6999999880791,"domainLookupStart":679.6999999880791,"fetchStart":679.6999999880791,"redirectEnd":0,"redirectStart":0,"requestStart":679.6999999880791,"responseEnd":874.8000000119209,"responseStart":874.8000000119209,"secureConnectionStart":679.6999999880791},{"duration":366.9000000357628,"initiatorType":"link","name":"https://jira.mariadb.org/s/d5715adaadd168a9002b108b2b039b50-CDN/lu2bu7/820016/12ta74/be4b45e9cec53099498fa61c8b7acba4/_/download/contextbatch/css/jira.project.sidebar,-_super,-project.issue.navigator,-jira.general,-jira.browse.project,-jira.view.issue,-jira.global,-atl.general,-com.atlassian.jira.projects.sidebar.init/batch.css?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&slack-enabled=true","startTime":936.8999999761581,"connectEnd":0,"connectStart":0,"domainLookupEnd":0,"domainLookupStart":0,"fetchStart":936.8999999761581,"redirectEnd":0,"redirectStart":0,"requestStart":0,"responseEnd":1303.800000011921,"responseStart":0,"secureConnectionStart":0},{"duration":367.10000002384186,"initiatorType":"script","name":"https://jira.mariadb.org/s/d41d8cd98f00b204e9800998ecf8427e-CDN/lu2bu7/820016/12ta74/e65b778d185daf5aee24936755b43da6/_/download/contextbatch/js/browser-metrics-plugin.contrib,-_super,-project.issue.navigator,-jira.view.issue,-atl.general/batch.js?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&slack-enabled=true","startTime":937.6999999880791,"connectEnd":937.6999999880791,"connectStart":937.6999999880791,"domainLookupEnd":937.6999999880791,"domainLookupStart":937.6999999880791,"fetchStart":937.6999999880791,"redirectEnd":0,"redirectStart":0,"requestStart":937.6999999880791,"responseEnd":1304.800000011921,"responseStart":1304.800000011921,"secureConnectionStart":937.6999999880791},{"duration":403.5999999642372,"initiatorType":"script","name":"https://jira.mariadb.org/s/f51ef5507eea4c158f257c66c93b2a3f-CDN/lu2bu7/820016/12ta74/be4b45e9cec53099498fa61c8b7acba4/_/download/contextbatch/js/jira.project.sidebar,-_super,-project.issue.navigator,-jira.general,-jira.browse.project,-jira.view.issue,-jira.global,-atl.general,-com.atlassian.jira.projects.sidebar.init/batch.js?agile_global_admin_condition=true&jag=true&jira.create.linked.issue=true&locale=en&slack-enabled=true","startTime":938.1000000238419,"connectEnd":938.1000000238419,"connectStart":938.1000000238419,"domainLookupEnd":938.1000000238419,"domainLookupStart":938.1000000238419,"fetchStart":938.1000000238419,"redirectEnd":0,"redirectStart":0,"requestStart":938.1000000238419,"responseEnd":1341.699999988079,"responseStart":1341.699999988079,"secureConnectionStart":938.1000000238419}],"fetchStart":0,"domainLookupStart":0,"domainLookupEnd":0,"connectStart":0,"connectEnd":0,"requestStart":83,"responseStart":280,"responseEnd":313,"domLoading":283,"domInteractive":1340,"domContentLoadedEventStart":1340,"domContentLoadedEventEnd":1394,"domComplete":1814,"loadEventStart":1814,"loadEventEnd":1815,"userAgent":"Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)","marks":[{"name":"bigPipe.sidebar-id.start","time":1305.199999988079},{"name":"bigPipe.sidebar-id.end","time":1306.1000000238419},{"name":"bigPipe.activity-panel-pipe-id.start","time":1306.199999988079},{"name":"bigPipe.activity-panel-pipe-id.end","time":1311},{"name":"activityTabFullyLoaded","time":1413.6000000238419}],"measures":[],"correlationId":"96d4dd526e9175","effectiveType":"4g","downlink":10,"rtt":0,"serverDuration":124,"dbReadsTimeInMs":14,"dbConnsTimeInMs":23,"applicationHash":"9d11dbea5f4be3d4cc21f03a88dd11d8c8687422","experiments":[]}}
Also, a table referencing another table is somewhat similar to foreign keys. And for them the privilege is checked on creation, not on every check.