summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-02-27 20:13:51 +0100
committerSergei Golubchik <serg@mariadb.org>2015-02-28 19:48:22 +0100
commitba80708f66fca32c7c2fbc66879177e5590e53fb (patch)
tree65dded9078148beac96f20bf5b833e2de231b306
parent7951bb16565e84a87d5289fa3eb4450bdf50ab96 (diff)
downloadmariadb-git-ba80708f66fca32c7c2fbc66879177e5590e53fb.tar.gz
MDEV-6960 Server crashes in check_alter_user on setting a default role via PS
There were two issues: * set_var_default_role::user was overwritten with a new value, allocated in the thd->mem_root, which is reset between executions. That was causing the crash. Solved by introducing set_var_default_role::real_user * when privilege tables were opened on EXECUTE, the reprepare_observer would abort the statement (as privilege tables are opened using the local TABLE_LIST that doesn't preserve metadata from PREPARE, so reprepare_observer thought they're changed). This issue also applied to SET PASSWORD. Solved by disabling reprepare_observer.
-rw-r--r--mysql-test/suite/roles/set_default_role_ps-6960.result8
-rw-r--r--mysql-test/suite/roles/set_default_role_ps-6960.test15
-rw-r--r--sql/set_var.cc16
-rw-r--r--sql/set_var.h2
4 files changed, 36 insertions, 5 deletions
diff --git a/mysql-test/suite/roles/set_default_role_ps-6960.result b/mysql-test/suite/roles/set_default_role_ps-6960.result
new file mode 100644
index 00000000000..60210d7f92c
--- /dev/null
+++ b/mysql-test/suite/roles/set_default_role_ps-6960.result
@@ -0,0 +1,8 @@
+create role r1;
+prepare stmt from "set password = '11111111111111111111111111111111111111111'";
+execute stmt;
+prepare stmt from "set default role r1";
+execute stmt;
+set password = '';
+set default role NONE;
+drop role r1;
diff --git a/mysql-test/suite/roles/set_default_role_ps-6960.test b/mysql-test/suite/roles/set_default_role_ps-6960.test
new file mode 100644
index 00000000000..8ac520e1776
--- /dev/null
+++ b/mysql-test/suite/roles/set_default_role_ps-6960.test
@@ -0,0 +1,15 @@
+#
+# MDEV-6960 Server crashes in check_alter_user on setting a default role via PS
+#
+
+--source include/not_embedded.inc
+
+create role r1;
+prepare stmt from "set password = '11111111111111111111111111111111111111111'";
+execute stmt;
+prepare stmt from "set default role r1";
+execute stmt;
+
+set password = '';
+set default role NONE;
+drop role r1;
diff --git a/sql/set_var.cc b/sql/set_var.cc
index e994745db68..278a05213a6 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -860,7 +860,11 @@ int set_var_password::check(THD *thd)
int set_var_password::update(THD *thd)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- return change_password(thd, user);
+ Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
+ thd->m_reprepare_observer= 0;
+ int res= change_password(thd, user);
+ thd->m_reprepare_observer= save_reprepare_observer;
+ return res;
#else
return 0;
#endif
@@ -896,8 +900,8 @@ int set_var_role::update(THD *thd)
int set_var_default_role::check(THD *thd)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- user= get_current_user(thd, user);
- int status= acl_check_set_default_role(thd, user->host.str, user->user.str);
+ real_user= get_current_user(thd, user);
+ int status= acl_check_set_default_role(thd, real_user->host.str, real_user->user.str);
return status;
#else
return 0;
@@ -907,7 +911,11 @@ int set_var_default_role::check(THD *thd)
int set_var_default_role::update(THD *thd)
{
#ifndef NO_EMBEDDED_ACCESS_CHECKS
- return acl_set_default_role(thd, user->host.str, user->user.str, role.str);
+ Reprepare_observer *save_reprepare_observer= thd->m_reprepare_observer;
+ thd->m_reprepare_observer= 0;
+ int res= acl_set_default_role(thd, real_user->host.str, real_user->user.str, role.str);
+ thd->m_reprepare_observer= save_reprepare_observer;
+ return res;
#else
return 0;
#endif
diff --git a/sql/set_var.h b/sql/set_var.h
index 66d1bc4e983..15c89f1e2b4 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -344,7 +344,7 @@ public:
class set_var_default_role: public set_var_base
{
- LEX_USER *user;
+ LEX_USER *user, *real_user;
LEX_STRING role;
public:
set_var_default_role(LEX_USER *user_arg, LEX_STRING role_arg) :