Commit de20091f authored by Alexander Barkov's avatar Alexander Barkov

MDEV-22755 CREATE USER leads to indirect SIGABRT in __stack_chk_fail () from...

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.
parent ae3a7d5e
...@@ -2633,3 +2633,16 @@ ERROR 42000: Access denied for user 'untrusted'@'localhost' to database 'secret' ...@@ -2633,3 +2633,16 @@ ERROR 42000: Access denied for user 'untrusted'@'localhost' to database 'secret'
DROP USER untrusted@localhost; DROP USER untrusted@localhost;
DROP DATABASE secret; DROP DATABASE secret;
set GLOBAL sql_mode=default; set GLOBAL sql_mode=default;
#
# MDEV-22755 CREATE USER leads to indirect SIGABRT in __stack_chk_fail () from fill_schema_user_privileges + *** stack smashing detected *** (on optimized builds)
#
SET NAMES utf8;
SET SQL_MODE='';
CREATE USER 觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻@localhost;
SELECT * FROM INFORMATION_SCHEMA.user_privileges WHERE GRANTEE LIKE "'abcdefghijklmnopqrstuvwxyz'%";
GRANTEE TABLE_CATALOG PRIVILEGE_TYPE IS_GRANTABLE
SELECT GRANTEE FROM INFORMATION_SCHEMA.user_privileges WHERE GRANTEE LIKE '%觻%';
GRANTEE
'觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻'@'localhost'
DROP USER 觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻@localhost;
SET SQL_MODE=DEFAULT;
...@@ -2292,3 +2292,16 @@ DROP DATABASE secret; ...@@ -2292,3 +2292,16 @@ DROP DATABASE secret;
set GLOBAL sql_mode=default; set GLOBAL sql_mode=default;
# Wait till we reached the initial number of concurrent sessions # Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc --source include/wait_until_count_sessions.inc
--echo #
--echo # MDEV-22755 CREATE USER leads to indirect SIGABRT in __stack_chk_fail () from fill_schema_user_privileges + *** stack smashing detected *** (on optimized builds)
--echo #
SET NAMES utf8;
SET SQL_MODE='';
CREATE USER 觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻@localhost;
SELECT * FROM INFORMATION_SCHEMA.user_privileges WHERE GRANTEE LIKE "'abcdefghijklmnopqrstuvwxyz'%";
SELECT GRANTEE FROM INFORMATION_SCHEMA.user_privileges WHERE GRANTEE LIKE '%觻%';
DROP USER 觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻_觻觻觻觻觻觻觻觻觻觻@localhost;
SET SQL_MODE=DEFAULT;
...@@ -10710,7 +10710,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr) ...@@ -10710,7 +10710,7 @@ int wild_case_compare(CHARSET_INFO *cs, const char *str,const char *wildstr)
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
static bool update_schema_privilege(THD *thd, TABLE *table, char *buff, static bool update_schema_privilege(THD *thd, TABLE *table, const char *buff,
const char* db, const char* t_name, const char* db, const char* t_name,
const char* column, uint col_length, const char* column, uint col_length,
const char *priv, uint priv_length, const char *priv, uint priv_length,
...@@ -10734,6 +10734,21 @@ static bool update_schema_privilege(THD *thd, TABLE *table, char *buff, ...@@ -10734,6 +10734,21 @@ static bool update_schema_privilege(THD *thd, TABLE *table, char *buff,
#endif #endif
#ifndef NO_EMBEDDED_ACCESS_CHECKS
class Grantee_str
{
char m_buff[USER_HOST_BUFF_SIZE + 6 /* 4 quotes, @, '\0' */];
public:
Grantee_str(const char *user, const char *host)
{
DBUG_ASSERT(strlen(user) + strlen(host) + 6 < sizeof(m_buff));
strxmov(m_buff, "'", user, "'@'", host, "'", NullS);
}
operator const char *() const { return m_buff; }
};
#endif
int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
{ {
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
...@@ -10741,7 +10756,6 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -10741,7 +10756,6 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
uint counter; uint counter;
ACL_USER *acl_user; ACL_USER *acl_user;
ulong want_access; ulong want_access;
char buff[100];
TABLE *table= tables->table; TABLE *table= tables->table;
bool no_global_access= check_access(thd, SELECT_ACL, "mysql", bool no_global_access= check_access(thd, SELECT_ACL, "mysql",
NULL, NULL, 1, 1); NULL, NULL, 1, 1);
...@@ -10768,10 +10782,10 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -10768,10 +10782,10 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
if (!(want_access & GRANT_ACL)) if (!(want_access & GRANT_ACL))
is_grantable= "NO"; is_grantable= "NO";
strxmov(buff,"'",user,"'@'",host,"'",NullS); Grantee_str grantee(user, host);
if (!(want_access & ~GRANT_ACL)) if (!(want_access & ~GRANT_ACL))
{ {
if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0, if (update_schema_privilege(thd, table, grantee, 0, 0, 0, 0,
STRING_WITH_LEN("USAGE"), is_grantable)) STRING_WITH_LEN("USAGE"), is_grantable))
{ {
error= 1; error= 1;
...@@ -10786,7 +10800,7 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -10786,7 +10800,7 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
{ {
if (test_access & j) if (test_access & j)
{ {
if (update_schema_privilege(thd, table, buff, 0, 0, 0, 0, if (update_schema_privilege(thd, table, grantee, 0, 0, 0, 0,
command_array[priv_id], command_array[priv_id],
command_lengths[priv_id], is_grantable)) command_lengths[priv_id], is_grantable))
{ {
...@@ -10814,7 +10828,6 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -10814,7 +10828,6 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
uint counter; uint counter;
ACL_DB *acl_db; ACL_DB *acl_db;
ulong want_access; ulong want_access;
char buff[100];
TABLE *table= tables->table; TABLE *table= tables->table;
bool no_global_access= check_access(thd, SELECT_ACL, "mysql", bool no_global_access= check_access(thd, SELECT_ACL, "mysql",
NULL, NULL, 1, 1); NULL, NULL, 1, 1);
...@@ -10845,10 +10858,10 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -10845,10 +10858,10 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
{ {
is_grantable= "NO"; is_grantable= "NO";
} }
strxmov(buff,"'",user,"'@'",host,"'",NullS); Grantee_str grantee(user, host);
if (!(want_access & ~GRANT_ACL)) if (!(want_access & ~GRANT_ACL))
{ {
if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0, if (update_schema_privilege(thd, table, grantee, acl_db->db, 0, 0,
0, STRING_WITH_LEN("USAGE"), is_grantable)) 0, STRING_WITH_LEN("USAGE"), is_grantable))
{ {
error= 1; error= 1;
...@@ -10862,7 +10875,8 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -10862,7 +10875,8 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1) for (cnt=0, j = SELECT_ACL; j <= DB_ACLS; cnt++,j <<= 1)
if (test_access & j) if (test_access & j)
{ {
if (update_schema_privilege(thd, table, buff, acl_db->db, 0, 0, 0, if (update_schema_privilege(thd, table,
grantee, acl_db->db, 0, 0, 0,
command_array[cnt], command_lengths[cnt], command_array[cnt], command_lengths[cnt],
is_grantable)) is_grantable))
{ {
...@@ -10888,7 +10902,6 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -10888,7 +10902,6 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
int error= 0; int error= 0;
uint index; uint index;
char buff[100];
TABLE *table= tables->table; TABLE *table= tables->table;
bool no_global_access= check_access(thd, SELECT_ACL, "mysql", bool no_global_access= check_access(thd, SELECT_ACL, "mysql",
NULL, NULL, 1, 1); NULL, NULL, 1, 1);
...@@ -10923,10 +10936,11 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -10923,10 +10936,11 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
if (!(table_access & GRANT_ACL)) if (!(table_access & GRANT_ACL))
is_grantable= "NO"; is_grantable= "NO";
strxmov(buff, "'", user, "'@'", host, "'", NullS); Grantee_str grantee(user, host);
if (!test_access) if (!test_access)
{ {
if (update_schema_privilege(thd, table, buff, grant_table->db, if (update_schema_privilege(thd, table,
grantee, grant_table->db,
grant_table->tname, 0, 0, grant_table->tname, 0, 0,
STRING_WITH_LEN("USAGE"), is_grantable)) STRING_WITH_LEN("USAGE"), is_grantable))
{ {
...@@ -10942,7 +10956,8 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -10942,7 +10956,8 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
{ {
if (test_access & j) if (test_access & j)
{ {
if (update_schema_privilege(thd, table, buff, grant_table->db, if (update_schema_privilege(thd, table,
grantee, grant_table->db,
grant_table->tname, 0, 0, grant_table->tname, 0, 0,
command_array[cnt], command_array[cnt],
command_lengths[cnt], is_grantable)) command_lengths[cnt], is_grantable))
...@@ -10970,7 +10985,6 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -10970,7 +10985,6 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
#ifndef NO_EMBEDDED_ACCESS_CHECKS #ifndef NO_EMBEDDED_ACCESS_CHECKS
int error= 0; int error= 0;
uint index; uint index;
char buff[100];
TABLE *table= tables->table; TABLE *table= tables->table;
bool no_global_access= check_access(thd, SELECT_ACL, "mysql", bool no_global_access= check_access(thd, SELECT_ACL, "mysql",
NULL, NULL, 1, 1); NULL, NULL, 1, 1);
...@@ -10999,7 +11013,7 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -10999,7 +11013,7 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
is_grantable= "NO"; is_grantable= "NO";
ulong test_access= table_access & ~GRANT_ACL; ulong test_access= table_access & ~GRANT_ACL;
strxmov(buff, "'", user, "'@'", host, "'", NullS); Grantee_str grantee(user, host);
if (!test_access) if (!test_access)
continue; continue;
else else
...@@ -11018,7 +11032,9 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond) ...@@ -11018,7 +11032,9 @@ int fill_schema_column_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
my_hash_element(&grant_table->hash_columns,col_index); my_hash_element(&grant_table->hash_columns,col_index);
if ((grant_column->rights & j) && (table_access & j)) if ((grant_column->rights & j) && (table_access & j))
{ {
if (update_schema_privilege(thd, table, buff, grant_table->db, if (update_schema_privilege(thd, table,
grantee,
grant_table->db,
grant_table->tname, grant_table->tname,
grant_column->column, grant_column->column,
grant_column->key_length, grant_column->key_length,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment