summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2013-06-12 20:29:19 +0200
committerSergei Golubchik <sergii@pisem.net>2013-06-12 20:29:19 +0200
commitdacb3809a2a88e8562bf3021afafa490d37de166 (patch)
treec92482c652fd77c1bebf28e37f764305b3f02344 /sql
parentf722b15dc23e6a0ca587553d35982e0936b1de9f (diff)
downloadmariadb-git-dacb3809a2a88e8562bf3021afafa490d37de166.tar.gz
MDEV-4422 SHOW PROCESSLIST reference to THD::db not protected against simultaneous updates
protect THD::db with THD::LOCK_thd_data
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_class.h12
-rw-r--r--sql/sql_show.cc4
2 files changed, 12 insertions, 4 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 52acba682a2..b11e18777d5 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1605,6 +1605,7 @@ public:
Protects THD data accessed from other threads:
- thd->query and thd->query_length (used by SHOW ENGINE
INNODB STATUS and SHOW PROCESSLIST
+ - thd->db and thd->db_length (used in SHOW PROCESSLIST)
- thd->mysys_var (used by KILL statement and shutdown).
Is locked when THD is deleted.
*/
@@ -2838,6 +2839,7 @@ public:
*/
bool set_db(const char *new_db, size_t new_db_len)
{
+ mysql_mutex_lock(&LOCK_thd_data);
/* Do not reallocate memory if current chunk is big enough. */
if (db && new_db && db_length >= new_db_len)
memcpy(db, new_db, new_db_len+1);
@@ -2850,6 +2852,7 @@ public:
db= NULL;
}
db_length= db ? new_db_len : 0;
+ mysql_mutex_unlock(&LOCK_thd_data);
return new_db && !db;
}
@@ -2866,8 +2869,13 @@ public:
*/
void reset_db(char *new_db, size_t new_db_len)
{
- db= new_db;
- db_length= new_db_len;
+ if (new_db != db || new_db_len != db_length)
+ {
+ mysql_mutex_lock(&LOCK_thd_data);
+ db= new_db;
+ db_length= new_db_len;
+ mysql_mutex_unlock(&LOCK_thd_data);
+ }
}
/*
Copy the current database to the argument. Use the current arena to
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 0229660be8d..3786fb7c22f 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2212,10 +2212,10 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
tmp_sctx->host_or_ip :
tmp_sctx->host ? tmp_sctx->host : "");
- if ((thd_info->db=tmp->db)) // Safe test
- thd_info->db=thd->strdup(thd_info->db);
thd_info->command=(int) tmp->command;
mysql_mutex_lock(&tmp->LOCK_thd_data);
+ if ((thd_info->db= tmp->db)) // Safe test
+ thd_info->db= thd->strdup(thd_info->db);
if ((mysys_var= tmp->mysys_var))
mysql_mutex_lock(&mysys_var->mutex);
thd_info->proc_info= (char*) (tmp->killed >= KILL_QUERY ?