Skip to content

Commit c283626

Browse files
Kristofer Petterssondahlerlend
authored andcommitted
Bug#24447966 SEGMENTATION FAULT IN MY_ATOMIC_ADD64 IN ATOMIC/GCC_SYNC.H
If acl_load() fails unexpectedly (example by using a KILL) the acl cache is deleted and not reinitialzied. This later causes a null pointer to be dereferenced when the acl cache version number should be increased. The fix is to not delete the acl cache.
1 parent 48670b9 commit c283626

File tree

3 files changed

+77
-1
lines changed

3 files changed

+77
-1
lines changed

mysql-test/r/grant_debug.result

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,43 @@ DROP USER user_name_robert_golebiowski1234@oh_my_gosh_this_is_a_long_hostname_lo
3030
DROP USER user_name_robert_golebiowski1234@localhost;
3131
DROP USER some_user@localhost;
3232
DROP DATABASE db_1;
33+
#
34+
# If acl_load() fails unexpectedly we shouldn't delete the acl cache
35+
#
36+
use test;
37+
CREATE ROLE r1,r2;
38+
CREATE USER u1@localhost IDENTIFIED BY 'foo';
39+
GRANT all on *.* to u1@localhost;
40+
GRANT r1,r2 TO u1@localhost;
41+
GRANT ALL ON *.* TO r1;
42+
SHOW GRANTS FOR u1@localhost USING r1;
43+
Grants for u1@localhost
44+
GRANT ALL PRIVILEGES ON *.* TO `u1`@`localhost`
45+
GRANT `r1`@`%`,`r2`@`%` TO `u1`@`localhost`
46+
ALTER USER u1@localhost DEFAULT ROLE r1;
47+
SET DEBUG='+d,induce_acl_load_failure';
48+
GRANT r1 TO r2;
49+
FLUSH PRIVILEGES;
50+
ERROR HY000: Unknown error
51+
SHOW GRANTS;
52+
Grants for u1@localhost
53+
GRANT ALL PRIVILEGES ON *.* TO `u1`@`localhost`
54+
GRANT `r1`@`%`,`r2`@`%` TO `u1`@`localhost`
55+
REVOKE r1 FROM r2;
56+
SET DEBUG='+d,induce_acl_load_failure';
57+
FLUSH PRIVILEGES;
58+
ERROR HY000: Unknown error
59+
# Grant should not have changed
60+
SHOW GRANTS FOR u1@localhost USING r1;
61+
Grants for u1@localhost
62+
GRANT ALL PRIVILEGES ON *.* TO `u1`@`localhost`
63+
GRANT `r1`@`%`,`r2`@`%` TO `u1`@`localhost`
64+
# Grant should not have changed
65+
SHOW GRANTS;
66+
Grants for u1@localhost
67+
GRANT ALL PRIVILEGES ON *.* TO `u1`@`localhost`
68+
GRANT `r1`@`%`,`r2`@`%` TO `u1`@`localhost`
69+
SET DEBUG='-d,induce_acl_load_failure';
70+
FLUSH PRIVILEGES;
71+
DROP USER u1@localhost;
72+
DROP ROLE r1,r2;

mysql-test/t/grant_debug.test

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,37 @@ DROP DATABASE db_1;
4949
--connection default
5050
--disconnect con_1
5151

52+
--echo #
53+
--echo # If acl_load() fails unexpectedly we shouldn't delete the acl cache
54+
--echo #
55+
use test;
56+
CREATE ROLE r1,r2;
57+
CREATE USER u1@localhost IDENTIFIED BY 'foo';
58+
GRANT all on *.* to u1@localhost;
59+
GRANT r1,r2 TO u1@localhost;
60+
GRANT ALL ON *.* TO r1;
61+
SHOW GRANTS FOR u1@localhost USING r1;
62+
ALTER USER u1@localhost DEFAULT ROLE r1;
63+
SET DEBUG='+d,induce_acl_load_failure';
64+
GRANT r1 TO r2;
65+
--error ER_UNKNOWN_ERROR
66+
FLUSH PRIVILEGES;
67+
connect (con1,localhost,u1,foo,);
68+
SHOW GRANTS;
69+
connection default;
70+
REVOKE r1 FROM r2;
71+
SET DEBUG='+d,induce_acl_load_failure';
72+
--error ER_UNKNOWN_ERROR
73+
FLUSH PRIVILEGES;
74+
--echo # Grant should not have changed
75+
SHOW GRANTS FOR u1@localhost USING r1;
76+
connection con1;
77+
--echo # Grant should not have changed
78+
SHOW GRANTS;
79+
connection default;
80+
disconnect con1;
81+
SET DEBUG='-d,induce_acl_load_failure';
82+
FLUSH PRIVILEGES;
83+
DROP USER u1@localhost;
84+
DROP ROLE r1,r2;
85+

sql/auth/sql_auth_cache.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2172,6 +2172,8 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
21722172
thd->variables.sql_mode= old_sql_mode;
21732173
if (table_schema)
21742174
delete table_schema;
2175+
DBUG_EXECUTE_IF("induce_acl_load_failure",
2176+
return_val= TRUE;);
21752177
DBUG_RETURN(return_val);
21762178
}
21772179

@@ -2180,7 +2182,6 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables)
21802182

21812183
void acl_free(bool end)
21822184
{
2183-
shutdown_acl_cache();
21842185
free_root(&global_acl_memory,MYF(0));
21852186
delete acl_users;
21862187
acl_users= NULL;
@@ -2195,6 +2196,7 @@ void acl_free(bool end)
21952196
clear_and_init_db_cache();
21962197
else
21972198
{
2199+
shutdown_acl_cache();
21982200
if (acl_cache_initialized == true)
21992201
{
22002202
my_hash_free(&db_cache);

0 commit comments

Comments
 (0)