summaryrefslogtreecommitdiff
path: root/sql/sql_acl.cc
diff options
context:
space:
mode:
authorArun Kuruvila <arun.kuruvila@oracle.com>2015-10-14 11:08:49 +0530
committerArun Kuruvila <arun.kuruvila@oracle.com>2015-10-14 11:08:49 +0530
commit3846b085521bce8e4600d4860dc3f2ea5f2ceb2d (patch)
tree038d8997c3e56f5696638451561b98e5aaaa717b /sql/sql_acl.cc
parentf92dd6ae6fb8922122049957b6ab7e07b6518bc2 (diff)
downloadmariadb-git-3846b085521bce8e4600d4860dc3f2ea5f2ceb2d.tar.gz
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()".
Diffstat (limited to 'sql/sql_acl.cc')
-rw-r--r--sql/sql_acl.cc8
1 files changed, 8 insertions, 0 deletions
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);