summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorPraveenkumar Hulakund <praveenkumar.hulakund@oracle.com>2013-08-21 10:44:22 +0530
committerPraveenkumar Hulakund <praveenkumar.hulakund@oracle.com>2013-08-21 10:44:22 +0530
commit7fffec875ac3be244affff4c86b34bd61af11487 (patch)
tree5c64842b7b3ffcc46f6bbc2bd7bfa57e93d207b2 /sql
parentfcc0011438caaf94f7716ffe4e99bab2e7d17be1 (diff)
parent3b1e98d21844b0f32f6e5fe9df447046eb471453 (diff)
downloadmariadb-git-7fffec875ac3be244affff4c86b34bd61af11487.tar.gz
Bug#11765252 - READ OF FREED MEMORY WHEN "USE DB" AND
"SHOW PROCESSLIST" Merging from 5.1 to 5.5
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_class.h9
-rw-r--r--sql/sql_db.cc9
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_show.cc12
4 files changed, 22 insertions, 10 deletions
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 64c05fe87c9..2c574e4fa33 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -2642,6 +2642,12 @@ public:
*/
bool set_db(const char *new_db, size_t new_db_len)
{
+ /*
+ Acquiring mutex LOCK_thd_data as we either free the memory allocated
+ for the database and reallocating the memory for the new db or memcpy
+ the new_db to the db.
+ */
+ 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);
@@ -2654,6 +2660,7 @@ public:
db= NULL;
}
db_length= db ? new_db_len : 0;
+ mysql_mutex_unlock(&LOCK_thd_data);
return new_db && !db;
}
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index ee02e811f67..ef83239bebf 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -1,5 +1,5 @@
/*
- Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1302,9 +1302,12 @@ static void mysql_change_db_impl(THD *thd,
we just call THD::reset_db(). Since THD::reset_db() does not releases
the previous database name, we should do it explicitly.
*/
- my_free(thd->db);
-
+ mysql_mutex_lock(&thd->LOCK_thd_data);
+ if (thd->db)
+ my_free(thd->db);
+ DEBUG_SYNC(thd, "after_freeing_thd_db");
thd->reset_db(new_db_name->str, new_db_name->length);
+ mysql_mutex_unlock(&thd->LOCK_thd_data);
}
/* 2. Update security context. */
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index dac42457a87..7e510fb1d50 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -979,7 +979,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (save_user_connect)
decrease_user_connections(save_user_connect);
#endif /* NO_EMBEDDED_ACCESS_CHECKS */
+ mysql_mutex_lock(&thd->LOCK_thd_data);
my_free(save_db);
+ mysql_mutex_unlock(&thd->LOCK_thd_data);
my_free(save_security_ctx.user);
}
break;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index fbd163f4667..01aea327ccf 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1843,10 +1843,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 == THD::KILL_CONNECTION? "Killed" : 0);
@@ -1920,7 +1920,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
{
Security_context *tmp_sctx= tmp->security_ctx;
struct st_my_thread_var *mysys_var;
- const char *val;
+ const char *val, *db;
if ((!tmp->vio_ok() && !tmp->system_thread) ||
(user && (!tmp_sctx->user || strcmp(tmp_sctx->user, user))))
@@ -1946,13 +1946,13 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
table->field[2]->store(tmp_sctx->host_or_ip,
strlen(tmp_sctx->host_or_ip), cs);
/* DB */
- if (tmp->db)
+ mysql_mutex_lock(&tmp->LOCK_thd_data);
+ if ((db= tmp->db))
{
- table->field[3]->store(tmp->db, strlen(tmp->db), cs);
+ table->field[3]->store(db, strlen(db), cs);
table->field[3]->set_notnull();
}
- mysql_mutex_lock(&tmp->LOCK_thd_data);
if ((mysys_var= tmp->mysys_var))
mysql_mutex_lock(&mysys_var->mutex);
/* COMMAND */