From aaaf6ceb8bcdfec103fd3131ff8261138d8b5e39 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Sat, 21 Dec 2019 13:46:33 +0400 Subject: MDE-21369 rpl.rpl_timezone fails with valgrind: Use of uninitialised value. It's not safe to chenge the THD::thread_id. So send the thread_id as an argument to the mysql_audit_external_lock. --- sql/sql_audit.h | 22 ++++++++++++++++------ sql/sql_insert.cc | 41 +++++++++++------------------------------ 2 files changed, 27 insertions(+), 36 deletions(-) (limited to 'sql') diff --git a/sql/sql_audit.h b/sql/sql_audit.h index ff0f049779f..03f2f3aca33 100644 --- a/sql/sql_audit.h +++ b/sql/sql_audit.h @@ -291,7 +291,9 @@ void mysql_audit_notify_connection_change_user(THD *thd) } static inline -void mysql_audit_external_lock(THD *thd, TABLE_SHARE *share, int lock) +void mysql_audit_external_lock_ex(THD *thd, my_thread_id thread_id, + const char *user, const char *host, const char *ip, query_id_t query_id, + TABLE_SHARE *share, int lock) { if (lock != F_UNLCK && mysql_audit_table_enabled()) { @@ -300,14 +302,14 @@ void mysql_audit_external_lock(THD *thd, TABLE_SHARE *share, int lock) event.event_subclass= MYSQL_AUDIT_TABLE_LOCK; event.read_only= lock == F_RDLCK; - event.thread_id= (unsigned long)thd->thread_id; - event.user= sctx->user; + event.thread_id= (unsigned long)thread_id; + event.user= user; event.priv_user= sctx->priv_user; event.priv_host= sctx->priv_host; event.external_user= sctx->external_user; event.proxy_user= sctx->proxy_user; - event.host= sctx->host; - event.ip= sctx->ip; + event.host= host; + event.ip= ip; event.database= share->db.str; event.database_length= (unsigned int)share->db.length; event.table= share->table_name.str; @@ -316,12 +318,20 @@ void mysql_audit_external_lock(THD *thd, TABLE_SHARE *share, int lock) event.new_database_length= 0; event.new_table= 0; event.new_table_length= 0; - event.query_id= thd->query_id; + event.query_id= query_id; mysql_audit_notify(thd, MYSQL_AUDIT_TABLE_CLASS, &event); } } +static inline +void mysql_audit_external_lock(THD *thd, TABLE_SHARE *share, int lock) +{ + mysql_audit_external_lock_ex(thd, thd->thread_id, thd->security_ctx->user, + thd->security_ctx->host, thd->security_ctx->ip, thd->query_id, + share, lock); +} + static inline void mysql_audit_create_table(TABLE *table) { diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index a312a8652c4..ec784bc6df4 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -2076,36 +2076,16 @@ public: passed from connection thread to the handler thread. */ MDL_request grl_protection; - my_thread_id orig_thread_id; - void set_default_user() - { - thd.security_ctx->user=(char*) delayed_user; - thd.security_ctx->host=(char*) my_localhost; - thd.security_ctx->ip= NULL; - thd.query_id= 0; - thd.thread_id= orig_thread_id; - } - - void set_user_from_row(const delayed_row *r) - { - if (r) - { - thd.security_ctx->user= r->user; - thd.security_ctx->host= r->host; - thd.security_ctx->ip= r->ip; - thd.query_id= r->query_id; - thd.thread_id= r->thread_id; - } - } - Delayed_insert(SELECT_LEX *current_select) :locks_in_memory(0), thd(next_thread_id()), table(0),tables_in_use(0), stacked_inserts(0), status(0), retry(0), handler_thread_initialized(FALSE), group_count(0) { DBUG_ENTER("Delayed_insert constructor"); - orig_thread_id= thd.thread_id; - set_default_user(); + thd.security_ctx->user=(char*) delayed_user; + thd.security_ctx->host=(char*) my_localhost; + thd.security_ctx->ip= NULL; + thd.query_id= 0; strmake_buf(thd.security_ctx->priv_user, thd.security_ctx->user); thd.current_tablenr=0; thd.set_command(COM_DELAYED_INSERT); @@ -3081,7 +3061,6 @@ pthread_handler_t handle_delayed_insert(void *arg) if (di->tables_in_use && ! thd->lock && !thd->killed) { - di->set_user_from_row(di->rows.head()); /* Request for new delayed insert. Lock the table, but avoid to be blocked by a global read lock. @@ -3103,16 +3082,18 @@ pthread_handler_t handle_delayed_insert(void *arg) { delayed_row *row; I_List_iterator it(di->rows); + my_thread_id cur_thd= di->thd.thread_id; + while ((row= it++)) { - if (di->thd.thread_id != row->thread_id) + if (cur_thd != row->thread_id) { - di->set_user_from_row(row); - mysql_audit_external_lock(&di->thd, di->table->s, F_WRLCK); + mysql_audit_external_lock_ex(&di->thd, row->thread_id, + row->user, row->host, row->ip, row->query_id, + di->table->s, F_WRLCK); + cur_thd= row->thread_id; } } - di->set_default_user(); - if (di->handle_inserts()) { /* Some fatal error */ -- cgit v1.2.1