Skip to content

Commit de20091

Browse files
committed
MDEV-22755 CREATE USER leads to indirect SIGABRT in __stack_chk_fail () from fill_schema_user_privileges + *** stack smashing detected *** (on optimized builds)
The code erroneously used buff[100] in a fiew places to make a GRANTEE value in the form: 'user'@'host' Fix: - Fixing the code to use (USER_HOST_BUFF_SIZE + 6) instead of 100. - Adding a DBUG_ASSERT to make sure the buffer is enough - Wrapping the code into a class Grantee_str, to reuse it easier in 4 places.
1 parent ae3a7d5 commit de20091

File tree

3 files changed

+58
-16
lines changed

3 files changed

+58
-16
lines changed

mysql-test/r/grant.result

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2633,3 +2633,16 @@ ERROR 42000: Access denied for user 'untrusted'@'localhost' to database 'secret'
26332633
DROP USER untrusted@localhost;
26342634
DROP DATABASE secret;
26352635
set GLOBAL sql_mode=default;
2636+
#
2637+
# MDEV-22755 CREATE USER leads to indirect SIGABRT in __stack_chk_fail () from fill_schema_user_privileges + *** stack smashing detected *** (on optimized builds)
2638+
#
2639+
SET NAMES utf8;
2640+
SET SQL_MODE='';
2641+
CREATE USER 觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻@localhost;
2642+
SELECT * FROM INFORMATION_SCHEMA.user_privileges WHERE GRANTEE LIKE "'abcdefghijklmnopqrstuvwxyz'%";
2643+
GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE
2644+
SELECT GRANTEE FROM INFORMATION_SCHEMA.user_privileges WHERE GRANTEE LIKE '%觻%';
2645+
GRANTEE
2646+
'觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻'@'localhost'
2647+
DROP USER 觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻@localhost;
2648+
SET SQL_MODE=DEFAULT;

mysql-test/t/grant.test

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2292,3 +2292,16 @@ DROP DATABASE secret;
22922292
set GLOBAL sql_mode=default;
22932293
# Wait till we reached the initial number of concurrent sessions
22942294
--source include/wait_until_count_sessions.inc
2295+
2296+
2297+
--echo #
2298+
--echo # MDEV-22755 CREATE USER leads to indirect SIGABRT in __stack_chk_fail () from fill_schema_user_privileges + *** stack smashing detected *** (on optimized builds)
2299+
--echo #
2300+
2301+
SET NAMES utf8;
2302+
SET SQL_MODE='';
2303+
CREATE USER 觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻@localhost;
2304+
SELECT * FROM INFORMATION_SCHEMA.user_privileges WHERE GRANTEE LIKE "'abcdefghijklmnopqrstuvwxyz'%";
2305+
SELECT GRANTEE FROM INFORMATION_SCHEMA.user_privileges WHERE GRANTEE LIKE '%觻%';
2306+
DROP USER 觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻@localhost;
2307+
SET SQL_MODE=DEFAULT;

sql/sql_acl.cc

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10710,7 +10710,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr)
1071010710

1071110711

1071210712
#ifndef NO_EMBEDDED_ACCESS_CHECKS
10713-
static bool update_schema_privilege(THD *thd, TABLE *table, char *buff,
10713+
static bool update_schema_privilege(THD *thd, TABLE *table, const char *buff,
1071410714
const char* db, const char* t_name,
1071510715
const char* column, uint col_length,
1071610716
const char *priv, uint priv_length,
@@ -10734,14 +10734,28 @@ static bool update_schema_privilege(THD *thd, TABLE *table, char *buff,
1073410734
#endif
1073510735

1073610736

10737+
#ifndef NO_EMBEDDED_ACCESS_CHECKS
10738+
class Grantee_str
10739+
{
10740+
char m_buff[USER_HOST_BUFF_SIZE + 6 /* 4 quotes, @, '\0' */];
10741+
public:
10742+
Grantee_str(const char *user, const char *host)
10743+
{
10744+
DBUG_ASSERT(strlen(user) + strlen(host) + 6 < sizeof(m_buff));
10745+
strxmov(m_buff, "'", user, "'@'", host, "'", NullS);
10746+
}
10747+
operator const char *() const { return m_buff; }
10748+
};
10749+
#endif
10750+
10751+
1073710752
int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
1073810753
{
1073910754
#ifndef NO_EMBEDDED_ACCESS_CHECKS
1074010755
int error= 0;
1074110756
uint counter;
1074210757
ACL_USER *acl_user;
1074310758
ulong want_access;
10744-
char buff[100];
1074510759
TABLE *table= tables->table;
1074610760
bool no_global_access= check_access(thd, SELECT_ACL, "mysql",
1074710761
NULL, NULL, 1, 1);
@@ -10768,10 +10782,10 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
1076810782
if (!(want_access & GRANT_ACL))
1076910783
is_grantable= "NO";
1077010784

10771-
strxmov(buff,"'",user,"'@'",host,"'",NullS);
10785+
Grantee_str grantee(user, host);
1077210786
if (!(want_access & ~GRANT_ACL))
1077310787
{
10774-
if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0,
10788+
if (update_schema_privilege(thd, table, grantee, 0, 0, 0, 0,
1077510789
STRING_WITH_LEN("USAGE"), is_grantable))
1077610790
{
1077710791
error= 1;
@@ -10786,7 +10800,7 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
1078610800
{
1078710801
if (test_access & j)
1078810802
{
10789-
if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0,
10803+
if (update_schema_privilege(thd, table, grantee, 0, 0, 0, 0,
1079010804
command_array[priv_id],
1079110805
command_lengths[priv_id], is_grantable))
1079210806
{
@@ -10814,7 +10828,6 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
1081410828
uint counter;
1081510829
ACL_DB *acl_db;
1081610830
ulong want_access;
10817-
char buff[100];
1081810831
TABLE *table= tables->table;
1081910832
bool no_global_access= check_access(thd, SELECT_ACL, "mysql",
1082010833
NULL, NULL, 1, 1);
@@ -10845,10 +10858,10 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
1084510858
{
1084610859
is_grantable= "NO";
1084710860
}
10848-
strxmov(buff,"'",user,"'@'",host,"'",NullS);
10861+
Grantee_str grantee(user, host);
1084910862
if (!(want_access & ~GRANT_ACL))
1085010863
{
10851-
if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0,
10864+
if (update_schema_privilege(thd, table, grantee, acl_db->db, 0, 0,
1085210865
0, STRING_WITH_LEN("USAGE"), is_grantable))
1085310866
{
1085410867
error= 1;
@@ -10862,7 +10875,8 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
1086210875
for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1)
1086310876
if (test_access & j)
1086410877
{
10865-
if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0, 0,
10878+
if (update_schema_privilege(thd, table,
10879+
grantee, acl_db->db, 0, 0, 0,
1086610880
command_array[cnt], command_lengths[cnt],
1086710881
is_grantable))
1086810882
{
@@ -10888,7 +10902,6 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
1088810902
#ifndef NO_EMBEDDED_ACCESS_CHECKS
1088910903
int error= 0;
1089010904
uint index;
10891-
char buff[100];
1089210905
TABLE *table= tables->table;
1089310906
bool no_global_access= check_access(thd, SELECT_ACL, "mysql",
1089410907
NULL, NULL, 1, 1);
@@ -10923,10 +10936,11 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
1092310936
if (!(table_access & GRANT_ACL))
1092410937
is_grantable= "NO";
1092510938

10926-
strxmov(buff, "'", user, "'@'", host, "'", NullS);
10939+
Grantee_str grantee(user, host);
1092710940
if (!test_access)
1092810941
{
10929-
if (update_schema_privilege(thd, table, buff, grant_table->db,
10942+
if (update_schema_privilege(thd, table,
10943+
grantee, grant_table->db,
1093010944
grant_table->tname, 0, 0,
1093110945
STRING_WITH_LEN("USAGE"), is_grantable))
1093210946
{
@@ -10942,7 +10956,8 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
1094210956
{
1094310957
if (test_access & j)
1094410958
{
10945-
if (update_schema_privilege(thd, table, buff, grant_table->db,
10959+
if (update_schema_privilege(thd, table,
10960+
grantee, grant_table->db,
1094610961
grant_table->tname, 0, 0,
1094710962
command_array[cnt],
1094810963
command_lengths[cnt], is_grantable))
@@ -10970,7 +10985,6 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
1097010985
#ifndef NO_EMBEDDED_ACCESS_CHECKS
1097110986
int error= 0;
1097210987
uint index;
10973-
char buff[100];
1097410988
TABLE *table= tables->table;
1097510989
bool no_global_access= check_access(thd, SELECT_ACL, "mysql",
1097610990
NULL, NULL, 1, 1);
@@ -10999,7 +11013,7 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
1099911013
is_grantable= "NO";
1100011014

1100111015
ulong test_access= table_access & ~GRANT_ACL;
11002-
strxmov(buff, "'", user, "'@'", host, "'", NullS);
11016+
Grantee_str grantee(user, host);
1100311017
if (!test_access)
1100411018
continue;
1100511019
else
@@ -11018,7 +11032,9 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
1101811032
my_hash_element(&grant_table->hash_columns,col_index);
1101911033
if ((grant_column->rights & j) && (table_access & j))
1102011034
{
11021-
if (update_schema_privilege(thd, table, buff, grant_table->db,
11035+
if (update_schema_privilege(thd, table,
11036+
grantee,
11037+
grant_table->db,
1102211038
grant_table->tname,
1102311039
grant_column->column,
1102411040
grant_column->key_length,

0 commit comments

Comments
 (0)