Skip to content

Commit f55ab9e

Browse files
author
holyfoot/hf@mysql.com/hfmain.(none)
committed
Bug #23675 Partitions: possible security breach via alter
now we return different error message if user doesn't have SELECT grants
1 parent 45fb6c9 commit f55ab9e

File tree

7 files changed

+63
-16
lines changed

7 files changed

+63
-16
lines changed

mysql-test/r/partition_grant.result

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,16 @@ revoke alter on mysqltest_1.* from mysqltest_1@localhost;
1919
alter table t1 drop partition p3;
2020
ERROR 42000: ALTER command denied to user 'mysqltest_1'@'localhost' for table 't1'
2121
revoke select,alter,drop on mysqltest_1.* from mysqltest_1@localhost;
22-
drop user mysqltest_1@localhost;
2322
drop table t1;
23+
create table t1 (s1 int);
24+
insert into t1 values (1);
25+
grant alter on mysqltest_1.* to mysqltest_1@localhost;
26+
alter table t1 partition by list (s1) (partition p1 values in (2));
27+
ERROR HY000: Table has no partition for some existing values
28+
grant select, alter on mysqltest_1.* to mysqltest_1@localhost;
29+
alter table t1 partition by list (s1) (partition p1 values in (2));
30+
ERROR HY000: Table has no partition for value 1
31+
drop table t1;
32+
drop user mysqltest_1@localhost;
2433
drop schema mysqltest_1;
2534
End of 5.1 tests

mysql-test/t/partition_grant.test

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,30 @@ disconnect conn3;
5252
connection default;
5353

5454
revoke select,alter,drop on mysqltest_1.* from mysqltest_1@localhost;
55-
drop user mysqltest_1@localhost;
5655
drop table t1;
56+
57+
#
58+
# Bug #23675 Partitions: possible security breach via alter
59+
#
60+
61+
create table t1 (s1 int);
62+
insert into t1 values (1);
63+
grant alter on mysqltest_1.* to mysqltest_1@localhost;
64+
connect (conn4,localhost,mysqltest_1,,mysqltest_1);
65+
connection conn4;
66+
--error 1514
67+
alter table t1 partition by list (s1) (partition p1 values in (2));
68+
connection default;
69+
grant select, alter on mysqltest_1.* to mysqltest_1@localhost;
70+
disconnect conn4;
71+
connect (conn5,localhost,mysqltest_1,,mysqltest_1);
72+
--error 1514
73+
alter table t1 partition by list (s1) (partition p1 values in (2));
74+
disconnect conn5;
75+
connection default;
76+
drop table t1;
77+
78+
drop user mysqltest_1@localhost;
5779
drop schema mysqltest_1;
5880

5981
--echo End of 5.1 tests

sql/mysql_priv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,7 @@ class THD;
598598
void close_thread_tables(THD *thd, bool locked=0, bool skip_derived=0);
599599
bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *tables);
600600
bool check_single_table_access(THD *thd, ulong privilege,
601-
TABLE_LIST *tables);
601+
TABLE_LIST *tables, bool no_errors);
602602
bool check_routine_access(THD *thd,ulong want_access,char *db,char *name,
603603
bool is_proc, bool no_errors);
604604
bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table);

sql/partition_info.cc

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -849,15 +849,27 @@ void partition_info::print_no_partition_found(TABLE *table)
849849
{
850850
char buf[100];
851851
char *buf_ptr= (char*)&buf;
852-
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
852+
TABLE_LIST table_list;
853853

854-
if (part_expr->null_value)
855-
buf_ptr= (char*)"NULL";
854+
bzero(&table_list, sizeof(table_list));
855+
table_list.db= table->s->db.str;
856+
table_list.table_name= table->s->table_name.str;
857+
858+
if (check_single_table_access(current_thd,
859+
SELECT_ACL, &table_list, TRUE))
860+
my_message(ER_NO_PARTITION_FOR_GIVEN_VALUE,
861+
ER(ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT), MYF(0));
856862
else
857-
longlong2str(err_value, buf,
858-
part_expr->unsigned_flag ? 10 : -10);
859-
my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0), buf_ptr);
860-
dbug_tmp_restore_column_map(table->read_set, old_map);
863+
{
864+
my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->read_set);
865+
if (part_expr->null_value)
866+
buf_ptr= (char*)"NULL";
867+
else
868+
longlong2str(err_value, buf,
869+
part_expr->unsigned_flag ? 10 : -10);
870+
my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0), buf_ptr);
871+
dbug_tmp_restore_column_map(table->read_set, old_map);
872+
}
861873
}
862874
/*
863875
Set up buffers and arrays for fields requiring preparation

sql/share/errmsg.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6053,3 +6053,5 @@ ER_DUP_ENTRY_WITH_KEY_NAME 23000 S1009
60536053
ER_BINLOG_PURGE_EMFILE
60546054
eng "Too many files opened, please execute the command again"
60556055
ger "Zu viele offene Dateien, bitte f�hren Sie den Befehl noch einmal aus"
6056+
ER_NO_PARTITION_FOR_GIVEN_VALUE_SILENT
6057+
eng "Table has no partition for some existing values"

sql/sql_base.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5781,7 +5781,7 @@ bool setup_tables_and_check_access(THD *thd,
57815781
{
57825782
if (leaves_tmp->belong_to_view &&
57835783
check_single_table_access(thd, first_table ? want_access_first :
5784-
want_access, leaves_tmp))
5784+
want_access, leaves_tmp, FALSE))
57855785
{
57865786
tables->hide_view_error(thd);
57875787
return TRUE;

sql/sql_parse.cc

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4433,14 +4433,16 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
44334433
thd Thread handler
44344434
privilege requested privilege
44354435
all_tables global table list of query
4436+
no_errors FALSE/TRUE - report/don't report error to
4437+
the client (using my_error() call).
44364438
44374439
RETURN
44384440
0 - OK
44394441
1 - access denied, error is sent to client
44404442
*/
44414443

44424444
bool check_single_table_access(THD *thd, ulong privilege,
4443-
TABLE_LIST *all_tables)
4445+
TABLE_LIST *all_tables, bool no_errors)
44444446
{
44454447
Security_context * backup_ctx= thd->security_ctx;
44464448

@@ -4456,12 +4458,12 @@ bool check_single_table_access(THD *thd, ulong privilege,
44564458
db_name= all_tables->db;
44574459

44584460
if (check_access(thd, privilege, db_name,
4459-
&all_tables->grant.privilege, 0, 0,
4461+
&all_tables->grant.privilege, 0, no_errors,
44604462
test(all_tables->schema_table)))
44614463
goto deny;
44624464

44634465
/* Show only 1 table for check_grant */
4464-
if (grant_option && check_grant(thd, privilege, all_tables, 0, 1, 0))
4466+
if (grant_option && check_grant(thd, privilege, all_tables, 0, 1, no_errors))
44654467
goto deny;
44664468

44674469
thd->security_ctx= backup_ctx;
@@ -4489,7 +4491,7 @@ bool check_single_table_access(THD *thd, ulong privilege,
44894491

44904492
bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
44914493
{
4492-
if (check_single_table_access (thd,privilege,all_tables))
4494+
if (check_single_table_access (thd,privilege,all_tables, FALSE))
44934495
return 1;
44944496

44954497
/* Check rights on tables of subselects and implictly opened tables */
@@ -4502,7 +4504,7 @@ bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
45024504
*/
45034505
if (view && subselects_tables->belong_to_view == view)
45044506
{
4505-
if (check_single_table_access (thd, privilege, subselects_tables))
4507+
if (check_single_table_access (thd, privilege, subselects_tables, FALSE))
45064508
return 1;
45074509
subselects_tables= subselects_tables->next_global;
45084510
}

0 commit comments

Comments
 (0)