From 3846b085521bce8e4600d4860dc3f2ea5f2ceb2d Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Wed, 14 Oct 2015 11:08:49 +0530 Subject: Bug #21602056 : CONCURRENT FLUSH PRIVILEGES + REVOKE/GRANT CRASHES IN WILD_CASE_COMPARE! Description:- Executing FLUSH PRIVILEGES and REVOKE/ GRANT concurrently crashes the server. Analysis:- Concurrent FLUSH PRIVILEGES and REVOKE/GRANT might trigger a small time frame in which REVOKE/GRANT fetches the "acl_proxy_user" information as a part of "acl_check_proxy_grant_access()". Meanwhile FLUSH PRIVILEGES deletes the old acl structures as a part of "acl_reload()". After which REVOKE/GRANT tries to access the hostname in "wild_case_compare()" which leads to a crash because of the invalid memory access. Fix:- Mutex lock on "acl_cache" is acquired before fetching "acl_proxy_user" information in "acl_check_proxy_grant_access()". --- sql/sql_acl.cc | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'sql/sql_acl.cc') diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index fea1a209c20..a939ae72ecb 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -50,6 +50,7 @@ #include "hostname.h" #include "sql_db.h" #include "sql_array.h" +#include "debug_sync.h" bool mysql_user_table_is_in_short_password_format= false; @@ -1194,6 +1195,8 @@ my_bool acl_reload(THD *thd) mysql_mutex_unlock(&acl_cache->lock); end: close_mysql_tables(thd); + + DEBUG_SYNC(thd, "after_acl_reload"); DBUG_RETURN(return_val); } @@ -7346,11 +7349,14 @@ acl_check_proxy_grant_access(THD *thd, const char *host, const char *user, DBUG_RETURN(FALSE); } + mysql_mutex_lock(&acl_cache->lock); + /* check for matching WITH PROXY rights */ for (uint i=0; i < acl_proxy_users.elements; i++) { ACL_PROXY_USER *proxy= dynamic_element(&acl_proxy_users, i, ACL_PROXY_USER *); + DEBUG_SYNC(thd, "before_proxy_matches"); if (proxy->matches(thd->security_ctx->get_host()->ptr(), thd->security_ctx->user, thd->security_ctx->get_ip()->ptr(), @@ -7358,10 +7364,12 @@ acl_check_proxy_grant_access(THD *thd, const char *host, const char *user, proxy->get_with_grant()) { DBUG_PRINT("info", ("found")); + mysql_mutex_unlock(&acl_cache->lock); DBUG_RETURN(FALSE); } } + mysql_mutex_unlock(&acl_cache->lock); my_error(ER_ACCESS_DENIED_NO_PASSWORD_ERROR, MYF(0), thd->security_ctx->user, thd->security_ctx->host_or_ip); -- cgit v1.2.1