Bug #38148 insert user() references uninitialized fields on a slave
Submitted: 15 Jul 2008 18:42 Modified: 15 Jul 2008 20:52
Reporter: Mark Callaghan Email Updates:
Status: Can't repeat Impact on me:
None 
Category:MySQL Server: Replication Severity:S3 (Non-critical)
Version:5.0.37 OS:Any
Assigned to: CPU Architecture:Any
Tags: replication, user

[15 Jul 2008 18:42] Mark Callaghan
Description:
When 'insert into foo values (user())' runs, 'select * from foo' on a slave will reference uninitialized values on the slave.

How to repeat:
Run this test using mysql-test-run --valgrind
source include/master-slave.inc;

create table t1 (u varchar(20));
insert into t1 values(user());
select * from t1;

save_master_pos;
connection slave;
sync_with_master;

--disable_query_log
select "--- On slave --" as "";
--enable_query_log
select u, length(u) from t1;

connection master;
drop table t1;

In var/log/slave.err, I get a few warnings from valgrind:
==8653== Thread 7:
==8653== Conditional jump or move depends on uninitialised value(s)
==8653==    at 0x8521833: my_utf8_uni (ctype-utf8.c:1953)
==8653==    by 0x81ECD96: well_formed_copy_nchars(charset_info_st*, char*, unsigned, charset_info_st*, char const*, unsigned, unsigned, char const**, char const**, char const**) (sql_string.cc:967)
==8653==    by 0x81D219F: Field_varstring::store(char const*, unsigned, charset_info_st*) (field.cc:6415)
==8653==    by 0x8150DE1: Item::save_in_field(Field*, bool) (item.cc:4326)
==8653==    by 0x824321D: fill_record(THD*, Field**, List<Item>&, bool) (sql_base.cc:5185)
==8653==    by 0x824488A: fill_record_n_invoke_before_triggers(THD*, Field**, List<Item>&, bool, Table_triggers_list*, trg_event_type) (sql_base.cc:5223)
==8653==    by 0x82887D7: mysql_insert(THD*, st_table_list*, List<Item>&, List<List<Item> >&, List<Item>&, List<Item>&, enum_duplicates, bool) (sql_insert.cc:608)
==8653==    by 0x8214599: mysql_execute_command(THD*) (sql_parse.cc:4410)
==8653==    by 0x821A347: mysql_parse(THD*, char*, unsigned) (sql_parse.cc:7210)
==8653==    by 0x82B206A: Query_log_event::exec_event(st_relay_log_info*, char const*, unsigned) (log_event.cc:1843)
==8653==    by 0x82B24F1: Query_log_event::exec_event(st_relay_log_info*) (log_event.cc:1712)
==8653==    by 0x8353FFA: exec_relay_log_event(THD*, st_relay_log_info*) (slave.cc:3568)
==8653==    by 0x8354A3E: handle_slave_sql (slave.cc:4276)
==8653==    by 0x6753CAB: pthread_start_thread (manager.c:310)
==8653==    by 0x6A8E129: clone (clone.S:119)
==8653==
==8653== Use of uninitialised value of size 4
==8653==    at 0x852838B: my_wc_mb_latin1 (ctype-latin1.c:383)
==8653==    by 0x81ECE18: well_formed_copy_nchars(charset_info_st*, char*, unsigned, charset_info_st*, char const*, unsigned, unsigned, char const**, char const**, char const**) (sql_string.cc:991)
==8653==    by 0x81D219F: Field_varstring::store(char const*, unsigned, charset_info_st*) (field.cc:6415)
==8653==    by 0x8150DE1: Item::save_in_field(Field*, bool) (item.cc:4326)
==8653==    by 0x824321D: fill_record(THD*, Field**, List<Item>&, bool) (sql_base.cc:5185)
==8653==    by 0x824488A: fill_record_n_invoke_before_triggers(THD*, Field**, List<Item>&, bool, Table_triggers_list*, trg_event_type) (sql_base.cc:5223)
==8653==    by 0x82887D7: mysql_insert(THD*, st_table_list*, List<Item>&, List<List<Item> >&, List<Item>&, List<Item>&, enum_duplicates, bool) (sql_insert.cc:608)
==8653==    by 0x8214599: mysql_execute_command(THD*) (sql_parse.cc:4410)
==8653==    by 0x821A347: mysql_parse(THD*, char*, unsigned) (sql_parse.cc:7210)
==8653==    by 0x82B206A: Query_log_event::exec_event(st_relay_log_info*, char const*, unsigned) (log_event.cc:1843)
==8653==    by 0x82B24F1: Query_log_event::exec_event(st_relay_log_info*) (log_event.cc:1712)
==8653==    by 0x8353FFA: exec_relay_log_event(THD*, st_relay_log_info*) (slave.cc:3568)
==8653==    by 0x8354A3E: handle_slave_sql (slave.cc:4276)
==8653==    by 0x6753CAB: pthread_start_thread (manager.c:310)
==8653==    by 0x6A8E129: clone (clone.S:119)

Suggested fix:
Add this code to the start of Item_func_user::init

  // For system threads (e.g. replication SQL thread) user may be empty.
  // Set the values here to avoid printing junk and referencing
  // uninitialized values later.
  if (!user)
    user= "";
  if (!host)
    host= "";
[15 Jul 2008 20:52] Sveta Smirnova
Thank you for the report.

I can not repeat described behavior with current development sources although bug is repeatable with version 5.0.37. Please upgrade.